diff --git a/examples/python/TestNamespace.py b/examples/python/TestNamespace.py
new file mode 100644
index 0000000..e7d2377
--- /dev/null
+++ b/examples/python/TestNamespace.py
@@ -0,0 +1,172 @@
+#! /usr/bin/env python
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from thrift.protocol import TCompactProtocol
+from thrift.transport import TSocket, TTransport
+
+from proxy import AccumuloProxy
+from proxy.ttypes import NamespacePermission, IteratorSetting, IteratorScope, AccumuloException
+
+
+def main():
+    transport = TSocket.TSocket('localhost', 42424)
+    transport = TTransport.TFramedTransport(transport)
+    protocol = TCompactProtocol.TCompactProtocol(transport)
+    client = AccumuloProxy.Client(protocol)
+    transport.open()
+    login = client.login('root', {'password': 'password'})
+
+    client.createLocalUser(login, 'user1', 'password1')
+
+    print client.listNamespaces(login)
+
+    # create a namespace and give the user1 all permissions
+    print 'creating namespace testing'
+    client.createNamespace(login, 'testing')
+    assert client.namespaceExists(login, 'testing')
+    print client.listNamespaces(login)
+
+    print 'testing namespace renaming'
+    client.renameNamespace(login, 'testing', 'testing2')
+    assert not client.namespaceExists(login, 'testing')
+    assert client.namespaceExists(login, 'testing2')
+    client.renameNamespace(login, 'testing2', 'testing')
+    assert not client.namespaceExists(login, 'testing2')
+    assert client.namespaceExists(login, 'testing')
+
+    print 'granting all namespace permissions to user1'
+    for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems():
+        client.grantNamespacePermission(login, 'user1', 'testing', k)
+
+    # make sure the last operation worked
+    for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems():
+        assert client.hasNamespacePermission(login, 'user1', 'testing', k), \
+            'user1 does\'nt have namespace permission %s' % v
+
+    print 'default namespace: ' + client.defaultNamespace()
+    print 'system namespace: ' + client.systemNamespace()
+
+    # grab the namespace properties
+    print 'retrieving namespace properties'
+    props = client.getNamespaceProperties(login, 'testing')
+    assert props and props['table.compaction.major.ratio'] == '3'
+
+    # update a property and verify it is good
+    print 'setting namespace property table.compaction.major.ratio = 4'
+    client.setNamespaceProperty(login, 'testing', 'table.compaction.major.ratio', '4')
+    props = client.getNamespaceProperties(login, 'testing')
+    assert props and props['table.compaction.major.ratio'] == '4'
+
+    print 'retrieving namespace ID map'
+    nsids = client.namespaceIdMap(login)
+    assert nsids and 'accumulo' in nsids
+
+    print 'attaching debug iterator to namespace testing'
+    setting = IteratorSetting(priority=40, name='DebugTheThings',
+                              iteratorClass='org.apache.accumulo.core.iterators.DebugIterator', properties={})
+    client.attachNamespaceIterator(login, 'testing', setting, [IteratorScope.SCAN])
+    setting = client.getNamespaceIteratorSetting(login, 'testing', 'DebugTheThings', IteratorScope.SCAN)
+    assert setting and setting.name == 'DebugTheThings'
+
+    # make sure the iterator is in the list
+    iters = client.listNamespaceIterators(login, 'testing')
+    found = False
+    for name, scopes in iters.iteritems():
+        if name == 'DebugTheThings':
+            found = True
+            break
+    assert found
+
+    print 'checking for iterator conflicts'
+
+    # this next statment should be fine since we are on a different scope
+    client.checkNamespaceIteratorConflicts(login, 'testing', setting, [IteratorScope.MINC])
+
+    # this time it should throw an exception since we have already added the iterator with this scope
+    try:
+        client.checkNamespaceIteratorConflicts(login, 'testing', setting, [IteratorScope.SCAN, IteratorScope.MINC])
+    except AccumuloException:
+        pass
+    else:
+        assert False, 'There should have been a namespace iterator conflict!'
+
+    print 'removing debug iterator from namespace testing'
+    client.removeNamespaceIterator(login, 'testing', 'DebugTheThings', [IteratorScope.SCAN])
+
+    # make sure the iterator is NOT in the list anymore
+    iters = client.listNamespaceIterators(login, 'testing')
+    found = False
+    for name, scopes in iters.iteritems():
+        if name == 'DebugTheThings':
+            found = True
+            break
+    assert not found
+
+    print 'adding max mutation size namespace constraint'
+    constraintid = client.addNamespaceConstraint(login, 'testing',
+                                                 'org.apache.accumulo.examples.simple.constraints.MaxMutationSize')
+
+    print 'make sure constraint was added'
+    constraints = client.listNamespaceConstraints(login, 'testing')
+    found = False
+    for name, cid in constraints.iteritems():
+        if cid == constraintid and name == 'org.apache.accumulo.examples.simple.constraints.MaxMutationSize':
+            found = True
+            break
+    assert found
+
+    print 'remove max mutation size namespace constraint'
+    client.removeNamespaceConstraint(login, 'testing', constraintid)
+
+    print 'make sure constraint was removed'
+    constraints = client.listNamespaceConstraints(login, 'testing')
+    found = False
+    for name, cid in constraints.iteritems():
+        if cid == constraintid and name == 'org.apache.accumulo.examples.simple.constraints.MaxMutationSize':
+            found = True
+            break
+    assert not found
+
+    print 'test a namespace class load of the VersioningIterator'
+    res = client.testNamespaceClassLoad(login, 'testing', 'org.apache.accumulo.core.iterators.user.VersioningIterator',
+                                        'org.apache.accumulo.core.iterators.SortedKeyValueIterator')
+    assert res
+
+    print 'test a bad namespace class load of the VersioningIterator'
+    res = client.testNamespaceClassLoad(login, 'testing', 'org.apache.accumulo.core.iterators.user.VersioningIterator',
+                                        'dummy')
+    assert not res
+
+    # revoke the permissions
+    print 'revoking namespace permissions for user1'
+    for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems():
+        client.revokeNamespacePermission(login, 'user1', 'testing', k)
+
+    # make sure the last operation worked
+    for k, v in NamespacePermission._VALUES_TO_NAMES.iteritems():
+        assert not client.hasNamespacePermission(login, 'user1', 'testing', k), \
+            'user1 does\'nt have namespace permission %s' % v
+
+    print 'deleting namespace testing'
+    client.deleteNamespace(login, 'testing')
+    assert not client.namespaceExists(login, 'testing')
+
+    print 'deleting user1'
+    client.dropLocalUser(login, 'user1')
+
+if __name__ == "__main__":
+    main()
diff --git a/pom.xml b/pom.xml
index 3a2c862..3435723 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.accumulo</groupId>
     <artifactId>accumulo-project</artifactId>
-    <version>1.7.3-SNAPSHOT</version>
+    <version>1.8.1-SNAPSHOT</version>
   </parent>
   <artifactId>accumulo-proxy</artifactId>
   <name>Apache Accumulo Proxy</name>
diff --git a/src/main/cpp/AccumuloProxy.cpp b/src/main/cpp/AccumuloProxy.cpp
index b220dcb..d0add35 100644
--- a/src/main/cpp/AccumuloProxy.cpp
+++ b/src/main/cpp/AccumuloProxy.cpp
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -24,8 +24,14 @@
 
 namespace accumulo {
 
+
+AccumuloProxy_login_args::~AccumuloProxy_login_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_login_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -56,17 +62,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->loginProperties.clear();
-            uint32_t _size133;
-            ::apache::thrift::protocol::TType _ktype134;
-            ::apache::thrift::protocol::TType _vtype135;
-            xfer += iprot->readMapBegin(_ktype134, _vtype135, _size133);
-            uint32_t _i137;
-            for (_i137 = 0; _i137 < _size133; ++_i137)
+            uint32_t _size195;
+            ::apache::thrift::protocol::TType _ktype196;
+            ::apache::thrift::protocol::TType _vtype197;
+            xfer += iprot->readMapBegin(_ktype196, _vtype197, _size195);
+            uint32_t _i199;
+            for (_i199 = 0; _i199 < _size195; ++_i199)
             {
-              std::string _key138;
-              xfer += iprot->readString(_key138);
-              std::string& _val139 = this->loginProperties[_key138];
-              xfer += iprot->readString(_val139);
+              std::string _key200;
+              xfer += iprot->readString(_key200);
+              std::string& _val201 = this->loginProperties[_key200];
+              xfer += iprot->readString(_val201);
             }
             xfer += iprot->readMapEnd();
           }
@@ -89,6 +95,7 @@
 
 uint32_t AccumuloProxy_login_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_login_args");
 
   xfer += oprot->writeFieldBegin("principal", ::apache::thrift::protocol::T_STRING, 1);
@@ -98,11 +105,11 @@
   xfer += oprot->writeFieldBegin("loginProperties", ::apache::thrift::protocol::T_MAP, 2);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->loginProperties.size()));
-    std::map<std::string, std::string> ::const_iterator _iter140;
-    for (_iter140 = this->loginProperties.begin(); _iter140 != this->loginProperties.end(); ++_iter140)
+    std::map<std::string, std::string> ::const_iterator _iter202;
+    for (_iter202 = this->loginProperties.begin(); _iter202 != this->loginProperties.end(); ++_iter202)
     {
-      xfer += oprot->writeString(_iter140->first);
-      xfer += oprot->writeString(_iter140->second);
+      xfer += oprot->writeString(_iter202->first);
+      xfer += oprot->writeString(_iter202->second);
     }
     xfer += oprot->writeMapEnd();
   }
@@ -113,8 +120,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_login_pargs::~AccumuloProxy_login_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_login_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_login_pargs");
 
   xfer += oprot->writeFieldBegin("principal", ::apache::thrift::protocol::T_STRING, 1);
@@ -124,11 +137,11 @@
   xfer += oprot->writeFieldBegin("loginProperties", ::apache::thrift::protocol::T_MAP, 2);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->loginProperties)).size()));
-    std::map<std::string, std::string> ::const_iterator _iter141;
-    for (_iter141 = (*(this->loginProperties)).begin(); _iter141 != (*(this->loginProperties)).end(); ++_iter141)
+    std::map<std::string, std::string> ::const_iterator _iter203;
+    for (_iter203 = (*(this->loginProperties)).begin(); _iter203 != (*(this->loginProperties)).end(); ++_iter203)
     {
-      xfer += oprot->writeString(_iter141->first);
-      xfer += oprot->writeString(_iter141->second);
+      xfer += oprot->writeString(_iter203->first);
+      xfer += oprot->writeString(_iter203->second);
     }
     xfer += oprot->writeMapEnd();
   }
@@ -139,8 +152,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_login_result::~AccumuloProxy_login_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_login_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -207,8 +226,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_login_presult::~AccumuloProxy_login_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_login_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -255,8 +280,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_addConstraint_args::~AccumuloProxy_addConstraint_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_addConstraint_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -313,6 +344,7 @@
 
 uint32_t AccumuloProxy_addConstraint_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_addConstraint_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -332,8 +364,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_addConstraint_pargs::~AccumuloProxy_addConstraint_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_addConstraint_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_addConstraint_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -353,8 +391,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_addConstraint_result::~AccumuloProxy_addConstraint_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_addConstraint_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -445,8 +489,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_addConstraint_presult::~AccumuloProxy_addConstraint_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_addConstraint_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -509,8 +559,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_addSplits_args::~AccumuloProxy_addSplits_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_addSplits_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -549,15 +605,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->splits.clear();
-            uint32_t _size142;
-            ::apache::thrift::protocol::TType _etype145;
-            xfer += iprot->readSetBegin(_etype145, _size142);
-            uint32_t _i146;
-            for (_i146 = 0; _i146 < _size142; ++_i146)
+            uint32_t _size204;
+            ::apache::thrift::protocol::TType _etype207;
+            xfer += iprot->readSetBegin(_etype207, _size204);
+            uint32_t _i208;
+            for (_i208 = 0; _i208 < _size204; ++_i208)
             {
-              std::string _elem147;
-              xfer += iprot->readBinary(_elem147);
-              this->splits.insert(_elem147);
+              std::string _elem209;
+              xfer += iprot->readBinary(_elem209);
+              this->splits.insert(_elem209);
             }
             xfer += iprot->readSetEnd();
           }
@@ -580,6 +636,7 @@
 
 uint32_t AccumuloProxy_addSplits_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_addSplits_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -593,10 +650,10 @@
   xfer += oprot->writeFieldBegin("splits", ::apache::thrift::protocol::T_SET, 3);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->splits.size()));
-    std::set<std::string> ::const_iterator _iter148;
-    for (_iter148 = this->splits.begin(); _iter148 != this->splits.end(); ++_iter148)
+    std::set<std::string> ::const_iterator _iter210;
+    for (_iter210 = this->splits.begin(); _iter210 != this->splits.end(); ++_iter210)
     {
-      xfer += oprot->writeBinary((*_iter148));
+      xfer += oprot->writeBinary((*_iter210));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -607,8 +664,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_addSplits_pargs::~AccumuloProxy_addSplits_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_addSplits_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_addSplits_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -622,10 +685,10 @@
   xfer += oprot->writeFieldBegin("splits", ::apache::thrift::protocol::T_SET, 3);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->splits)).size()));
-    std::set<std::string> ::const_iterator _iter149;
-    for (_iter149 = (*(this->splits)).begin(); _iter149 != (*(this->splits)).end(); ++_iter149)
+    std::set<std::string> ::const_iterator _iter211;
+    for (_iter211 = (*(this->splits)).begin(); _iter211 != (*(this->splits)).end(); ++_iter211)
     {
-      xfer += oprot->writeBinary((*_iter149));
+      xfer += oprot->writeBinary((*_iter211));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -636,8 +699,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_addSplits_result::~AccumuloProxy_addSplits_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_addSplits_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -716,8 +785,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_addSplits_presult::~AccumuloProxy_addSplits_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_addSplits_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -772,8 +847,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_attachIterator_args::~AccumuloProxy_attachIterator_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_attachIterator_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -820,17 +901,17 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->scopes.clear();
-            uint32_t _size150;
-            ::apache::thrift::protocol::TType _etype153;
-            xfer += iprot->readSetBegin(_etype153, _size150);
-            uint32_t _i154;
-            for (_i154 = 0; _i154 < _size150; ++_i154)
+            uint32_t _size212;
+            ::apache::thrift::protocol::TType _etype215;
+            xfer += iprot->readSetBegin(_etype215, _size212);
+            uint32_t _i216;
+            for (_i216 = 0; _i216 < _size212; ++_i216)
             {
-              IteratorScope::type _elem155;
-              int32_t ecast156;
-              xfer += iprot->readI32(ecast156);
-              _elem155 = (IteratorScope::type)ecast156;
-              this->scopes.insert(_elem155);
+              IteratorScope::type _elem217;
+              int32_t ecast218;
+              xfer += iprot->readI32(ecast218);
+              _elem217 = (IteratorScope::type)ecast218;
+              this->scopes.insert(_elem217);
             }
             xfer += iprot->readSetEnd();
           }
@@ -853,6 +934,7 @@
 
 uint32_t AccumuloProxy_attachIterator_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_attachIterator_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -870,10 +952,10 @@
   xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
-    std::set<IteratorScope::type> ::const_iterator _iter157;
-    for (_iter157 = this->scopes.begin(); _iter157 != this->scopes.end(); ++_iter157)
+    std::set<IteratorScope::type> ::const_iterator _iter219;
+    for (_iter219 = this->scopes.begin(); _iter219 != this->scopes.end(); ++_iter219)
     {
-      xfer += oprot->writeI32((int32_t)(*_iter157));
+      xfer += oprot->writeI32((int32_t)(*_iter219));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -884,8 +966,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_attachIterator_pargs::~AccumuloProxy_attachIterator_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_attachIterator_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_attachIterator_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -903,10 +991,10 @@
   xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
-    std::set<IteratorScope::type> ::const_iterator _iter158;
-    for (_iter158 = (*(this->scopes)).begin(); _iter158 != (*(this->scopes)).end(); ++_iter158)
+    std::set<IteratorScope::type> ::const_iterator _iter220;
+    for (_iter220 = (*(this->scopes)).begin(); _iter220 != (*(this->scopes)).end(); ++_iter220)
     {
-      xfer += oprot->writeI32((int32_t)(*_iter158));
+      xfer += oprot->writeI32((int32_t)(*_iter220));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -917,8 +1005,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_attachIterator_result::~AccumuloProxy_attachIterator_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_attachIterator_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -997,8 +1091,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_attachIterator_presult::~AccumuloProxy_attachIterator_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_attachIterator_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1053,8 +1153,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_checkIteratorConflicts_args::~AccumuloProxy_checkIteratorConflicts_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_checkIteratorConflicts_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1101,17 +1207,17 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->scopes.clear();
-            uint32_t _size159;
-            ::apache::thrift::protocol::TType _etype162;
-            xfer += iprot->readSetBegin(_etype162, _size159);
-            uint32_t _i163;
-            for (_i163 = 0; _i163 < _size159; ++_i163)
+            uint32_t _size221;
+            ::apache::thrift::protocol::TType _etype224;
+            xfer += iprot->readSetBegin(_etype224, _size221);
+            uint32_t _i225;
+            for (_i225 = 0; _i225 < _size221; ++_i225)
             {
-              IteratorScope::type _elem164;
-              int32_t ecast165;
-              xfer += iprot->readI32(ecast165);
-              _elem164 = (IteratorScope::type)ecast165;
-              this->scopes.insert(_elem164);
+              IteratorScope::type _elem226;
+              int32_t ecast227;
+              xfer += iprot->readI32(ecast227);
+              _elem226 = (IteratorScope::type)ecast227;
+              this->scopes.insert(_elem226);
             }
             xfer += iprot->readSetEnd();
           }
@@ -1134,6 +1240,7 @@
 
 uint32_t AccumuloProxy_checkIteratorConflicts_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_checkIteratorConflicts_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -1151,10 +1258,10 @@
   xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
-    std::set<IteratorScope::type> ::const_iterator _iter166;
-    for (_iter166 = this->scopes.begin(); _iter166 != this->scopes.end(); ++_iter166)
+    std::set<IteratorScope::type> ::const_iterator _iter228;
+    for (_iter228 = this->scopes.begin(); _iter228 != this->scopes.end(); ++_iter228)
     {
-      xfer += oprot->writeI32((int32_t)(*_iter166));
+      xfer += oprot->writeI32((int32_t)(*_iter228));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -1165,8 +1272,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_checkIteratorConflicts_pargs::~AccumuloProxy_checkIteratorConflicts_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_checkIteratorConflicts_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_checkIteratorConflicts_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -1184,10 +1297,10 @@
   xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
-    std::set<IteratorScope::type> ::const_iterator _iter167;
-    for (_iter167 = (*(this->scopes)).begin(); _iter167 != (*(this->scopes)).end(); ++_iter167)
+    std::set<IteratorScope::type> ::const_iterator _iter229;
+    for (_iter229 = (*(this->scopes)).begin(); _iter229 != (*(this->scopes)).end(); ++_iter229)
     {
-      xfer += oprot->writeI32((int32_t)(*_iter167));
+      xfer += oprot->writeI32((int32_t)(*_iter229));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -1198,8 +1311,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_checkIteratorConflicts_result::~AccumuloProxy_checkIteratorConflicts_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_checkIteratorConflicts_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1278,8 +1397,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_checkIteratorConflicts_presult::~AccumuloProxy_checkIteratorConflicts_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_checkIteratorConflicts_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1334,8 +1459,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_clearLocatorCache_args::~AccumuloProxy_clearLocatorCache_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_clearLocatorCache_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1384,6 +1515,7 @@
 
 uint32_t AccumuloProxy_clearLocatorCache_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_clearLocatorCache_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -1399,8 +1531,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_clearLocatorCache_pargs::~AccumuloProxy_clearLocatorCache_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_clearLocatorCache_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_clearLocatorCache_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -1416,8 +1554,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_clearLocatorCache_result::~AccumuloProxy_clearLocatorCache_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_clearLocatorCache_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1472,8 +1616,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_clearLocatorCache_presult::~AccumuloProxy_clearLocatorCache_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_clearLocatorCache_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1512,8 +1662,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_cloneTable_args::~AccumuloProxy_cloneTable_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_cloneTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1568,17 +1724,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->propertiesToSet.clear();
-            uint32_t _size168;
-            ::apache::thrift::protocol::TType _ktype169;
-            ::apache::thrift::protocol::TType _vtype170;
-            xfer += iprot->readMapBegin(_ktype169, _vtype170, _size168);
-            uint32_t _i172;
-            for (_i172 = 0; _i172 < _size168; ++_i172)
+            uint32_t _size230;
+            ::apache::thrift::protocol::TType _ktype231;
+            ::apache::thrift::protocol::TType _vtype232;
+            xfer += iprot->readMapBegin(_ktype231, _vtype232, _size230);
+            uint32_t _i234;
+            for (_i234 = 0; _i234 < _size230; ++_i234)
             {
-              std::string _key173;
-              xfer += iprot->readString(_key173);
-              std::string& _val174 = this->propertiesToSet[_key173];
-              xfer += iprot->readString(_val174);
+              std::string _key235;
+              xfer += iprot->readString(_key235);
+              std::string& _val236 = this->propertiesToSet[_key235];
+              xfer += iprot->readString(_val236);
             }
             xfer += iprot->readMapEnd();
           }
@@ -1591,15 +1747,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->propertiesToExclude.clear();
-            uint32_t _size175;
-            ::apache::thrift::protocol::TType _etype178;
-            xfer += iprot->readSetBegin(_etype178, _size175);
-            uint32_t _i179;
-            for (_i179 = 0; _i179 < _size175; ++_i179)
+            uint32_t _size237;
+            ::apache::thrift::protocol::TType _etype240;
+            xfer += iprot->readSetBegin(_etype240, _size237);
+            uint32_t _i241;
+            for (_i241 = 0; _i241 < _size237; ++_i241)
             {
-              std::string _elem180;
-              xfer += iprot->readString(_elem180);
-              this->propertiesToExclude.insert(_elem180);
+              std::string _elem242;
+              xfer += iprot->readString(_elem242);
+              this->propertiesToExclude.insert(_elem242);
             }
             xfer += iprot->readSetEnd();
           }
@@ -1622,6 +1778,7 @@
 
 uint32_t AccumuloProxy_cloneTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_cloneTable_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -1643,11 +1800,11 @@
   xfer += oprot->writeFieldBegin("propertiesToSet", ::apache::thrift::protocol::T_MAP, 5);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->propertiesToSet.size()));
-    std::map<std::string, std::string> ::const_iterator _iter181;
-    for (_iter181 = this->propertiesToSet.begin(); _iter181 != this->propertiesToSet.end(); ++_iter181)
+    std::map<std::string, std::string> ::const_iterator _iter243;
+    for (_iter243 = this->propertiesToSet.begin(); _iter243 != this->propertiesToSet.end(); ++_iter243)
     {
-      xfer += oprot->writeString(_iter181->first);
-      xfer += oprot->writeString(_iter181->second);
+      xfer += oprot->writeString(_iter243->first);
+      xfer += oprot->writeString(_iter243->second);
     }
     xfer += oprot->writeMapEnd();
   }
@@ -1656,10 +1813,10 @@
   xfer += oprot->writeFieldBegin("propertiesToExclude", ::apache::thrift::protocol::T_SET, 6);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->propertiesToExclude.size()));
-    std::set<std::string> ::const_iterator _iter182;
-    for (_iter182 = this->propertiesToExclude.begin(); _iter182 != this->propertiesToExclude.end(); ++_iter182)
+    std::set<std::string> ::const_iterator _iter244;
+    for (_iter244 = this->propertiesToExclude.begin(); _iter244 != this->propertiesToExclude.end(); ++_iter244)
     {
-      xfer += oprot->writeString((*_iter182));
+      xfer += oprot->writeString((*_iter244));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -1670,8 +1827,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_cloneTable_pargs::~AccumuloProxy_cloneTable_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_cloneTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_cloneTable_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -1693,11 +1856,11 @@
   xfer += oprot->writeFieldBegin("propertiesToSet", ::apache::thrift::protocol::T_MAP, 5);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->propertiesToSet)).size()));
-    std::map<std::string, std::string> ::const_iterator _iter183;
-    for (_iter183 = (*(this->propertiesToSet)).begin(); _iter183 != (*(this->propertiesToSet)).end(); ++_iter183)
+    std::map<std::string, std::string> ::const_iterator _iter245;
+    for (_iter245 = (*(this->propertiesToSet)).begin(); _iter245 != (*(this->propertiesToSet)).end(); ++_iter245)
     {
-      xfer += oprot->writeString(_iter183->first);
-      xfer += oprot->writeString(_iter183->second);
+      xfer += oprot->writeString(_iter245->first);
+      xfer += oprot->writeString(_iter245->second);
     }
     xfer += oprot->writeMapEnd();
   }
@@ -1706,10 +1869,10 @@
   xfer += oprot->writeFieldBegin("propertiesToExclude", ::apache::thrift::protocol::T_SET, 6);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->propertiesToExclude)).size()));
-    std::set<std::string> ::const_iterator _iter184;
-    for (_iter184 = (*(this->propertiesToExclude)).begin(); _iter184 != (*(this->propertiesToExclude)).end(); ++_iter184)
+    std::set<std::string> ::const_iterator _iter246;
+    for (_iter246 = (*(this->propertiesToExclude)).begin(); _iter246 != (*(this->propertiesToExclude)).end(); ++_iter246)
     {
-      xfer += oprot->writeString((*_iter184));
+      xfer += oprot->writeString((*_iter246));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -1720,8 +1883,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_cloneTable_result::~AccumuloProxy_cloneTable_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_cloneTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1812,8 +1981,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_cloneTable_presult::~AccumuloProxy_cloneTable_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_cloneTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1876,8 +2051,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_compactTable_args::~AccumuloProxy_compactTable_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_compactTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1932,14 +2113,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->iterators.clear();
-            uint32_t _size185;
-            ::apache::thrift::protocol::TType _etype188;
-            xfer += iprot->readListBegin(_etype188, _size185);
-            this->iterators.resize(_size185);
-            uint32_t _i189;
-            for (_i189 = 0; _i189 < _size185; ++_i189)
+            uint32_t _size247;
+            ::apache::thrift::protocol::TType _etype250;
+            xfer += iprot->readListBegin(_etype250, _size247);
+            this->iterators.resize(_size247);
+            uint32_t _i251;
+            for (_i251 = 0; _i251 < _size247; ++_i251)
             {
-              xfer += this->iterators[_i189].read(iprot);
+              xfer += this->iterators[_i251].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -1986,6 +2167,7 @@
 
 uint32_t AccumuloProxy_compactTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_compactTable_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -2007,10 +2189,10 @@
   xfer += oprot->writeFieldBegin("iterators", ::apache::thrift::protocol::T_LIST, 5);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->iterators.size()));
-    std::vector<IteratorSetting> ::const_iterator _iter190;
-    for (_iter190 = this->iterators.begin(); _iter190 != this->iterators.end(); ++_iter190)
+    std::vector<IteratorSetting> ::const_iterator _iter252;
+    for (_iter252 = this->iterators.begin(); _iter252 != this->iterators.end(); ++_iter252)
     {
-      xfer += (*_iter190).write(oprot);
+      xfer += (*_iter252).write(oprot);
     }
     xfer += oprot->writeListEnd();
   }
@@ -2033,8 +2215,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_compactTable_pargs::~AccumuloProxy_compactTable_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_compactTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_compactTable_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -2056,10 +2244,10 @@
   xfer += oprot->writeFieldBegin("iterators", ::apache::thrift::protocol::T_LIST, 5);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>((*(this->iterators)).size()));
-    std::vector<IteratorSetting> ::const_iterator _iter191;
-    for (_iter191 = (*(this->iterators)).begin(); _iter191 != (*(this->iterators)).end(); ++_iter191)
+    std::vector<IteratorSetting> ::const_iterator _iter253;
+    for (_iter253 = (*(this->iterators)).begin(); _iter253 != (*(this->iterators)).end(); ++_iter253)
     {
-      xfer += (*_iter191).write(oprot);
+      xfer += (*_iter253).write(oprot);
     }
     xfer += oprot->writeListEnd();
   }
@@ -2082,8 +2270,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_compactTable_result::~AccumuloProxy_compactTable_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_compactTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2162,8 +2356,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_compactTable_presult::~AccumuloProxy_compactTable_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_compactTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2218,8 +2418,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_cancelCompaction_args::~AccumuloProxy_cancelCompaction_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_cancelCompaction_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2268,6 +2474,7 @@
 
 uint32_t AccumuloProxy_cancelCompaction_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_cancelCompaction_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -2283,8 +2490,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_cancelCompaction_pargs::~AccumuloProxy_cancelCompaction_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_cancelCompaction_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_cancelCompaction_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -2300,8 +2513,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_cancelCompaction_result::~AccumuloProxy_cancelCompaction_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_cancelCompaction_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2380,8 +2599,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_cancelCompaction_presult::~AccumuloProxy_cancelCompaction_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_cancelCompaction_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2436,8 +2661,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createTable_args::~AccumuloProxy_createTable_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_createTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2482,9 +2713,9 @@
         break;
       case 4:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast192;
-          xfer += iprot->readI32(ecast192);
-          this->type = (TimeType::type)ecast192;
+          int32_t ecast254;
+          xfer += iprot->readI32(ecast254);
+          this->type = (TimeType::type)ecast254;
           this->__isset.type = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -2504,6 +2735,7 @@
 
 uint32_t AccumuloProxy_createTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createTable_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -2527,8 +2759,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createTable_pargs::~AccumuloProxy_createTable_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_createTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createTable_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -2552,8 +2790,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createTable_result::~AccumuloProxy_createTable_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_createTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2632,8 +2876,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createTable_presult::~AccumuloProxy_createTable_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_createTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2688,8 +2938,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_deleteTable_args::~AccumuloProxy_deleteTable_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_deleteTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2738,6 +2994,7 @@
 
 uint32_t AccumuloProxy_deleteTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_deleteTable_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -2753,8 +3010,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_deleteTable_pargs::~AccumuloProxy_deleteTable_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_deleteTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_deleteTable_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -2770,8 +3033,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_deleteTable_result::~AccumuloProxy_deleteTable_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_deleteTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2850,8 +3119,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_deleteTable_presult::~AccumuloProxy_deleteTable_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_deleteTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2906,8 +3181,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_deleteRows_args::~AccumuloProxy_deleteRows_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_deleteRows_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2972,6 +3253,7 @@
 
 uint32_t AccumuloProxy_deleteRows_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_deleteRows_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -2995,8 +3277,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_deleteRows_pargs::~AccumuloProxy_deleteRows_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_deleteRows_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_deleteRows_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -3020,8 +3308,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_deleteRows_result::~AccumuloProxy_deleteRows_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_deleteRows_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3100,8 +3394,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_deleteRows_presult::~AccumuloProxy_deleteRows_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_deleteRows_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3156,8 +3456,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_exportTable_args::~AccumuloProxy_exportTable_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_exportTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3214,6 +3520,7 @@
 
 uint32_t AccumuloProxy_exportTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_exportTable_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -3233,8 +3540,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_exportTable_pargs::~AccumuloProxy_exportTable_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_exportTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_exportTable_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -3254,8 +3567,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_exportTable_result::~AccumuloProxy_exportTable_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_exportTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3334,8 +3653,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_exportTable_presult::~AccumuloProxy_exportTable_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_exportTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3390,8 +3715,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_flushTable_args::~AccumuloProxy_flushTable_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_flushTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3464,6 +3795,7 @@
 
 uint32_t AccumuloProxy_flushTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_flushTable_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -3491,8 +3823,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_flushTable_pargs::~AccumuloProxy_flushTable_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_flushTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_flushTable_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -3520,8 +3858,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_flushTable_result::~AccumuloProxy_flushTable_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_flushTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3600,8 +3944,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_flushTable_presult::~AccumuloProxy_flushTable_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_flushTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3656,8 +4006,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getDiskUsage_args::~AccumuloProxy_getDiskUsage_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getDiskUsage_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3688,15 +4044,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->tables.clear();
-            uint32_t _size193;
-            ::apache::thrift::protocol::TType _etype196;
-            xfer += iprot->readSetBegin(_etype196, _size193);
-            uint32_t _i197;
-            for (_i197 = 0; _i197 < _size193; ++_i197)
+            uint32_t _size255;
+            ::apache::thrift::protocol::TType _etype258;
+            xfer += iprot->readSetBegin(_etype258, _size255);
+            uint32_t _i259;
+            for (_i259 = 0; _i259 < _size255; ++_i259)
             {
-              std::string _elem198;
-              xfer += iprot->readString(_elem198);
-              this->tables.insert(_elem198);
+              std::string _elem260;
+              xfer += iprot->readString(_elem260);
+              this->tables.insert(_elem260);
             }
             xfer += iprot->readSetEnd();
           }
@@ -3719,6 +4075,7 @@
 
 uint32_t AccumuloProxy_getDiskUsage_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getDiskUsage_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -3728,10 +4085,10 @@
   xfer += oprot->writeFieldBegin("tables", ::apache::thrift::protocol::T_SET, 2);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->tables.size()));
-    std::set<std::string> ::const_iterator _iter199;
-    for (_iter199 = this->tables.begin(); _iter199 != this->tables.end(); ++_iter199)
+    std::set<std::string> ::const_iterator _iter261;
+    for (_iter261 = this->tables.begin(); _iter261 != this->tables.end(); ++_iter261)
     {
-      xfer += oprot->writeString((*_iter199));
+      xfer += oprot->writeString((*_iter261));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -3742,8 +4099,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getDiskUsage_pargs::~AccumuloProxy_getDiskUsage_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getDiskUsage_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getDiskUsage_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -3753,10 +4116,10 @@
   xfer += oprot->writeFieldBegin("tables", ::apache::thrift::protocol::T_SET, 2);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->tables)).size()));
-    std::set<std::string> ::const_iterator _iter200;
-    for (_iter200 = (*(this->tables)).begin(); _iter200 != (*(this->tables)).end(); ++_iter200)
+    std::set<std::string> ::const_iterator _iter262;
+    for (_iter262 = (*(this->tables)).begin(); _iter262 != (*(this->tables)).end(); ++_iter262)
     {
-      xfer += oprot->writeString((*_iter200));
+      xfer += oprot->writeString((*_iter262));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -3767,8 +4130,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getDiskUsage_result::~AccumuloProxy_getDiskUsage_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getDiskUsage_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3791,14 +4160,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->success.clear();
-            uint32_t _size201;
-            ::apache::thrift::protocol::TType _etype204;
-            xfer += iprot->readListBegin(_etype204, _size201);
-            this->success.resize(_size201);
-            uint32_t _i205;
-            for (_i205 = 0; _i205 < _size201; ++_i205)
+            uint32_t _size263;
+            ::apache::thrift::protocol::TType _etype266;
+            xfer += iprot->readListBegin(_etype266, _size263);
+            this->success.resize(_size263);
+            uint32_t _i267;
+            for (_i267 = 0; _i267 < _size263; ++_i267)
             {
-              xfer += this->success[_i205].read(iprot);
+              xfer += this->success[_i267].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -3853,10 +4222,10 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
-      std::vector<DiskUsage> ::const_iterator _iter206;
-      for (_iter206 = this->success.begin(); _iter206 != this->success.end(); ++_iter206)
+      std::vector<DiskUsage> ::const_iterator _iter268;
+      for (_iter268 = this->success.begin(); _iter268 != this->success.end(); ++_iter268)
       {
-        xfer += (*_iter206).write(oprot);
+        xfer += (*_iter268).write(oprot);
       }
       xfer += oprot->writeListEnd();
     }
@@ -3879,8 +4248,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getDiskUsage_presult::~AccumuloProxy_getDiskUsage_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getDiskUsage_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3903,14 +4278,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             (*(this->success)).clear();
-            uint32_t _size207;
-            ::apache::thrift::protocol::TType _etype210;
-            xfer += iprot->readListBegin(_etype210, _size207);
-            (*(this->success)).resize(_size207);
-            uint32_t _i211;
-            for (_i211 = 0; _i211 < _size207; ++_i211)
+            uint32_t _size269;
+            ::apache::thrift::protocol::TType _etype272;
+            xfer += iprot->readListBegin(_etype272, _size269);
+            (*(this->success)).resize(_size269);
+            uint32_t _i273;
+            for (_i273 = 0; _i273 < _size269; ++_i273)
             {
-              xfer += (*(this->success))[_i211].read(iprot);
+              xfer += (*(this->success))[_i273].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -3955,8 +4330,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getLocalityGroups_args::~AccumuloProxy_getLocalityGroups_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getLocalityGroups_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4005,6 +4386,7 @@
 
 uint32_t AccumuloProxy_getLocalityGroups_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getLocalityGroups_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -4020,8 +4402,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getLocalityGroups_pargs::~AccumuloProxy_getLocalityGroups_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getLocalityGroups_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getLocalityGroups_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -4037,8 +4425,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getLocalityGroups_result::~AccumuloProxy_getLocalityGroups_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getLocalityGroups_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4061,27 +4455,27 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->success.clear();
-            uint32_t _size212;
-            ::apache::thrift::protocol::TType _ktype213;
-            ::apache::thrift::protocol::TType _vtype214;
-            xfer += iprot->readMapBegin(_ktype213, _vtype214, _size212);
-            uint32_t _i216;
-            for (_i216 = 0; _i216 < _size212; ++_i216)
+            uint32_t _size274;
+            ::apache::thrift::protocol::TType _ktype275;
+            ::apache::thrift::protocol::TType _vtype276;
+            xfer += iprot->readMapBegin(_ktype275, _vtype276, _size274);
+            uint32_t _i278;
+            for (_i278 = 0; _i278 < _size274; ++_i278)
             {
-              std::string _key217;
-              xfer += iprot->readString(_key217);
-              std::set<std::string> & _val218 = this->success[_key217];
+              std::string _key279;
+              xfer += iprot->readString(_key279);
+              std::set<std::string> & _val280 = this->success[_key279];
               {
-                _val218.clear();
-                uint32_t _size219;
-                ::apache::thrift::protocol::TType _etype222;
-                xfer += iprot->readSetBegin(_etype222, _size219);
-                uint32_t _i223;
-                for (_i223 = 0; _i223 < _size219; ++_i223)
+                _val280.clear();
+                uint32_t _size281;
+                ::apache::thrift::protocol::TType _etype284;
+                xfer += iprot->readSetBegin(_etype284, _size281);
+                uint32_t _i285;
+                for (_i285 = 0; _i285 < _size281; ++_i285)
                 {
-                  std::string _elem224;
-                  xfer += iprot->readString(_elem224);
-                  _val218.insert(_elem224);
+                  std::string _elem286;
+                  xfer += iprot->readString(_elem286);
+                  _val280.insert(_elem286);
                 }
                 xfer += iprot->readSetEnd();
               }
@@ -4139,16 +4533,16 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
     {
       xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_SET, static_cast<uint32_t>(this->success.size()));
-      std::map<std::string, std::set<std::string> > ::const_iterator _iter225;
-      for (_iter225 = this->success.begin(); _iter225 != this->success.end(); ++_iter225)
+      std::map<std::string, std::set<std::string> > ::const_iterator _iter287;
+      for (_iter287 = this->success.begin(); _iter287 != this->success.end(); ++_iter287)
       {
-        xfer += oprot->writeString(_iter225->first);
+        xfer += oprot->writeString(_iter287->first);
         {
-          xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(_iter225->second.size()));
-          std::set<std::string> ::const_iterator _iter226;
-          for (_iter226 = _iter225->second.begin(); _iter226 != _iter225->second.end(); ++_iter226)
+          xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(_iter287->second.size()));
+          std::set<std::string> ::const_iterator _iter288;
+          for (_iter288 = _iter287->second.begin(); _iter288 != _iter287->second.end(); ++_iter288)
           {
-            xfer += oprot->writeString((*_iter226));
+            xfer += oprot->writeString((*_iter288));
           }
           xfer += oprot->writeSetEnd();
         }
@@ -4174,8 +4568,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getLocalityGroups_presult::~AccumuloProxy_getLocalityGroups_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getLocalityGroups_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4198,27 +4598,27 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             (*(this->success)).clear();
-            uint32_t _size227;
-            ::apache::thrift::protocol::TType _ktype228;
-            ::apache::thrift::protocol::TType _vtype229;
-            xfer += iprot->readMapBegin(_ktype228, _vtype229, _size227);
-            uint32_t _i231;
-            for (_i231 = 0; _i231 < _size227; ++_i231)
+            uint32_t _size289;
+            ::apache::thrift::protocol::TType _ktype290;
+            ::apache::thrift::protocol::TType _vtype291;
+            xfer += iprot->readMapBegin(_ktype290, _vtype291, _size289);
+            uint32_t _i293;
+            for (_i293 = 0; _i293 < _size289; ++_i293)
             {
-              std::string _key232;
-              xfer += iprot->readString(_key232);
-              std::set<std::string> & _val233 = (*(this->success))[_key232];
+              std::string _key294;
+              xfer += iprot->readString(_key294);
+              std::set<std::string> & _val295 = (*(this->success))[_key294];
               {
-                _val233.clear();
-                uint32_t _size234;
-                ::apache::thrift::protocol::TType _etype237;
-                xfer += iprot->readSetBegin(_etype237, _size234);
-                uint32_t _i238;
-                for (_i238 = 0; _i238 < _size234; ++_i238)
+                _val295.clear();
+                uint32_t _size296;
+                ::apache::thrift::protocol::TType _etype299;
+                xfer += iprot->readSetBegin(_etype299, _size296);
+                uint32_t _i300;
+                for (_i300 = 0; _i300 < _size296; ++_i300)
                 {
-                  std::string _elem239;
-                  xfer += iprot->readString(_elem239);
-                  _val233.insert(_elem239);
+                  std::string _elem301;
+                  xfer += iprot->readString(_elem301);
+                  _val295.insert(_elem301);
                 }
                 xfer += iprot->readSetEnd();
               }
@@ -4266,8 +4666,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getIteratorSetting_args::~AccumuloProxy_getIteratorSetting_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getIteratorSetting_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4312,9 +4718,9 @@
         break;
       case 4:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast240;
-          xfer += iprot->readI32(ecast240);
-          this->scope = (IteratorScope::type)ecast240;
+          int32_t ecast302;
+          xfer += iprot->readI32(ecast302);
+          this->scope = (IteratorScope::type)ecast302;
           this->__isset.scope = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -4334,6 +4740,7 @@
 
 uint32_t AccumuloProxy_getIteratorSetting_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getIteratorSetting_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -4357,8 +4764,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getIteratorSetting_pargs::~AccumuloProxy_getIteratorSetting_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getIteratorSetting_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getIteratorSetting_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -4382,8 +4795,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getIteratorSetting_result::~AccumuloProxy_getIteratorSetting_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getIteratorSetting_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4474,8 +4893,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getIteratorSetting_presult::~AccumuloProxy_getIteratorSetting_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getIteratorSetting_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4538,8 +4963,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getMaxRow_args::~AccumuloProxy_getMaxRow_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getMaxRow_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4578,15 +5009,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->auths.clear();
-            uint32_t _size241;
-            ::apache::thrift::protocol::TType _etype244;
-            xfer += iprot->readSetBegin(_etype244, _size241);
-            uint32_t _i245;
-            for (_i245 = 0; _i245 < _size241; ++_i245)
+            uint32_t _size303;
+            ::apache::thrift::protocol::TType _etype306;
+            xfer += iprot->readSetBegin(_etype306, _size303);
+            uint32_t _i307;
+            for (_i307 = 0; _i307 < _size303; ++_i307)
             {
-              std::string _elem246;
-              xfer += iprot->readBinary(_elem246);
-              this->auths.insert(_elem246);
+              std::string _elem308;
+              xfer += iprot->readBinary(_elem308);
+              this->auths.insert(_elem308);
             }
             xfer += iprot->readSetEnd();
           }
@@ -4641,6 +5072,7 @@
 
 uint32_t AccumuloProxy_getMaxRow_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getMaxRow_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -4654,10 +5086,10 @@
   xfer += oprot->writeFieldBegin("auths", ::apache::thrift::protocol::T_SET, 3);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->auths.size()));
-    std::set<std::string> ::const_iterator _iter247;
-    for (_iter247 = this->auths.begin(); _iter247 != this->auths.end(); ++_iter247)
+    std::set<std::string> ::const_iterator _iter309;
+    for (_iter309 = this->auths.begin(); _iter309 != this->auths.end(); ++_iter309)
     {
-      xfer += oprot->writeBinary((*_iter247));
+      xfer += oprot->writeBinary((*_iter309));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -4684,8 +5116,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getMaxRow_pargs::~AccumuloProxy_getMaxRow_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getMaxRow_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getMaxRow_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -4699,10 +5137,10 @@
   xfer += oprot->writeFieldBegin("auths", ::apache::thrift::protocol::T_SET, 3);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->auths)).size()));
-    std::set<std::string> ::const_iterator _iter248;
-    for (_iter248 = (*(this->auths)).begin(); _iter248 != (*(this->auths)).end(); ++_iter248)
+    std::set<std::string> ::const_iterator _iter310;
+    for (_iter310 = (*(this->auths)).begin(); _iter310 != (*(this->auths)).end(); ++_iter310)
     {
-      xfer += oprot->writeBinary((*_iter248));
+      xfer += oprot->writeBinary((*_iter310));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -4729,8 +5167,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getMaxRow_result::~AccumuloProxy_getMaxRow_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getMaxRow_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4821,8 +5265,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getMaxRow_presult::~AccumuloProxy_getMaxRow_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getMaxRow_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4885,8 +5335,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getTableProperties_args::~AccumuloProxy_getTableProperties_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getTableProperties_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4935,6 +5391,7 @@
 
 uint32_t AccumuloProxy_getTableProperties_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getTableProperties_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -4950,8 +5407,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getTableProperties_pargs::~AccumuloProxy_getTableProperties_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getTableProperties_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getTableProperties_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -4967,8 +5430,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getTableProperties_result::~AccumuloProxy_getTableProperties_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getTableProperties_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -4991,17 +5460,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->success.clear();
-            uint32_t _size249;
-            ::apache::thrift::protocol::TType _ktype250;
-            ::apache::thrift::protocol::TType _vtype251;
-            xfer += iprot->readMapBegin(_ktype250, _vtype251, _size249);
-            uint32_t _i253;
-            for (_i253 = 0; _i253 < _size249; ++_i253)
+            uint32_t _size311;
+            ::apache::thrift::protocol::TType _ktype312;
+            ::apache::thrift::protocol::TType _vtype313;
+            xfer += iprot->readMapBegin(_ktype312, _vtype313, _size311);
+            uint32_t _i315;
+            for (_i315 = 0; _i315 < _size311; ++_i315)
             {
-              std::string _key254;
-              xfer += iprot->readString(_key254);
-              std::string& _val255 = this->success[_key254];
-              xfer += iprot->readString(_val255);
+              std::string _key316;
+              xfer += iprot->readString(_key316);
+              std::string& _val317 = this->success[_key316];
+              xfer += iprot->readString(_val317);
             }
             xfer += iprot->readMapEnd();
           }
@@ -5056,11 +5525,11 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
     {
       xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
-      std::map<std::string, std::string> ::const_iterator _iter256;
-      for (_iter256 = this->success.begin(); _iter256 != this->success.end(); ++_iter256)
+      std::map<std::string, std::string> ::const_iterator _iter318;
+      for (_iter318 = this->success.begin(); _iter318 != this->success.end(); ++_iter318)
       {
-        xfer += oprot->writeString(_iter256->first);
-        xfer += oprot->writeString(_iter256->second);
+        xfer += oprot->writeString(_iter318->first);
+        xfer += oprot->writeString(_iter318->second);
       }
       xfer += oprot->writeMapEnd();
     }
@@ -5083,8 +5552,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getTableProperties_presult::~AccumuloProxy_getTableProperties_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getTableProperties_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5107,17 +5582,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             (*(this->success)).clear();
-            uint32_t _size257;
-            ::apache::thrift::protocol::TType _ktype258;
-            ::apache::thrift::protocol::TType _vtype259;
-            xfer += iprot->readMapBegin(_ktype258, _vtype259, _size257);
-            uint32_t _i261;
-            for (_i261 = 0; _i261 < _size257; ++_i261)
+            uint32_t _size319;
+            ::apache::thrift::protocol::TType _ktype320;
+            ::apache::thrift::protocol::TType _vtype321;
+            xfer += iprot->readMapBegin(_ktype320, _vtype321, _size319);
+            uint32_t _i323;
+            for (_i323 = 0; _i323 < _size319; ++_i323)
             {
-              std::string _key262;
-              xfer += iprot->readString(_key262);
-              std::string& _val263 = (*(this->success))[_key262];
-              xfer += iprot->readString(_val263);
+              std::string _key324;
+              xfer += iprot->readString(_key324);
+              std::string& _val325 = (*(this->success))[_key324];
+              xfer += iprot->readString(_val325);
             }
             xfer += iprot->readMapEnd();
           }
@@ -5162,8 +5637,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_importDirectory_args::~AccumuloProxy_importDirectory_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_importDirectory_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5236,6 +5717,7 @@
 
 uint32_t AccumuloProxy_importDirectory_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_importDirectory_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -5263,8 +5745,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_importDirectory_pargs::~AccumuloProxy_importDirectory_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_importDirectory_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_importDirectory_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -5292,8 +5780,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_importDirectory_result::~AccumuloProxy_importDirectory_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_importDirectory_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5372,8 +5866,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_importDirectory_presult::~AccumuloProxy_importDirectory_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_importDirectory_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5428,8 +5928,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_importTable_args::~AccumuloProxy_importTable_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_importTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5486,6 +5992,7 @@
 
 uint32_t AccumuloProxy_importTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_importTable_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -5505,8 +6012,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_importTable_pargs::~AccumuloProxy_importTable_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_importTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_importTable_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -5526,8 +6039,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_importTable_result::~AccumuloProxy_importTable_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_importTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5606,8 +6125,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_importTable_presult::~AccumuloProxy_importTable_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_importTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5662,8 +6187,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listSplits_args::~AccumuloProxy_listSplits_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_listSplits_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5720,6 +6251,7 @@
 
 uint32_t AccumuloProxy_listSplits_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_listSplits_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -5739,8 +6271,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listSplits_pargs::~AccumuloProxy_listSplits_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_listSplits_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_listSplits_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -5760,8 +6298,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listSplits_result::~AccumuloProxy_listSplits_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_listSplits_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5784,14 +6328,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->success.clear();
-            uint32_t _size264;
-            ::apache::thrift::protocol::TType _etype267;
-            xfer += iprot->readListBegin(_etype267, _size264);
-            this->success.resize(_size264);
-            uint32_t _i268;
-            for (_i268 = 0; _i268 < _size264; ++_i268)
+            uint32_t _size326;
+            ::apache::thrift::protocol::TType _etype329;
+            xfer += iprot->readListBegin(_etype329, _size326);
+            this->success.resize(_size326);
+            uint32_t _i330;
+            for (_i330 = 0; _i330 < _size326; ++_i330)
             {
-              xfer += iprot->readBinary(this->success[_i268]);
+              xfer += iprot->readBinary(this->success[_i330]);
             }
             xfer += iprot->readListEnd();
           }
@@ -5846,10 +6390,10 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
-      std::vector<std::string> ::const_iterator _iter269;
-      for (_iter269 = this->success.begin(); _iter269 != this->success.end(); ++_iter269)
+      std::vector<std::string> ::const_iterator _iter331;
+      for (_iter331 = this->success.begin(); _iter331 != this->success.end(); ++_iter331)
       {
-        xfer += oprot->writeBinary((*_iter269));
+        xfer += oprot->writeBinary((*_iter331));
       }
       xfer += oprot->writeListEnd();
     }
@@ -5872,8 +6416,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listSplits_presult::~AccumuloProxy_listSplits_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_listSplits_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5896,14 +6446,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             (*(this->success)).clear();
-            uint32_t _size270;
-            ::apache::thrift::protocol::TType _etype273;
-            xfer += iprot->readListBegin(_etype273, _size270);
-            (*(this->success)).resize(_size270);
-            uint32_t _i274;
-            for (_i274 = 0; _i274 < _size270; ++_i274)
+            uint32_t _size332;
+            ::apache::thrift::protocol::TType _etype335;
+            xfer += iprot->readListBegin(_etype335, _size332);
+            (*(this->success)).resize(_size332);
+            uint32_t _i336;
+            for (_i336 = 0; _i336 < _size332; ++_i336)
             {
-              xfer += iprot->readBinary((*(this->success))[_i274]);
+              xfer += iprot->readBinary((*(this->success))[_i336]);
             }
             xfer += iprot->readListEnd();
           }
@@ -5948,8 +6498,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listTables_args::~AccumuloProxy_listTables_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_listTables_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -5990,6 +6546,7 @@
 
 uint32_t AccumuloProxy_listTables_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_listTables_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -6001,8 +6558,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listTables_pargs::~AccumuloProxy_listTables_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_listTables_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_listTables_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -6014,8 +6577,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listTables_result::~AccumuloProxy_listTables_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_listTables_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6038,15 +6607,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->success.clear();
-            uint32_t _size275;
-            ::apache::thrift::protocol::TType _etype278;
-            xfer += iprot->readSetBegin(_etype278, _size275);
-            uint32_t _i279;
-            for (_i279 = 0; _i279 < _size275; ++_i279)
+            uint32_t _size337;
+            ::apache::thrift::protocol::TType _etype340;
+            xfer += iprot->readSetBegin(_etype340, _size337);
+            uint32_t _i341;
+            for (_i341 = 0; _i341 < _size337; ++_i341)
             {
-              std::string _elem280;
-              xfer += iprot->readString(_elem280);
-              this->success.insert(_elem280);
+              std::string _elem342;
+              xfer += iprot->readString(_elem342);
+              this->success.insert(_elem342);
             }
             xfer += iprot->readSetEnd();
           }
@@ -6077,10 +6646,10 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_SET, 0);
     {
       xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
-      std::set<std::string> ::const_iterator _iter281;
-      for (_iter281 = this->success.begin(); _iter281 != this->success.end(); ++_iter281)
+      std::set<std::string> ::const_iterator _iter343;
+      for (_iter343 = this->success.begin(); _iter343 != this->success.end(); ++_iter343)
       {
-        xfer += oprot->writeString((*_iter281));
+        xfer += oprot->writeString((*_iter343));
       }
       xfer += oprot->writeSetEnd();
     }
@@ -6091,8 +6660,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listTables_presult::~AccumuloProxy_listTables_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_listTables_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6115,15 +6690,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             (*(this->success)).clear();
-            uint32_t _size282;
-            ::apache::thrift::protocol::TType _etype285;
-            xfer += iprot->readSetBegin(_etype285, _size282);
-            uint32_t _i286;
-            for (_i286 = 0; _i286 < _size282; ++_i286)
+            uint32_t _size344;
+            ::apache::thrift::protocol::TType _etype347;
+            xfer += iprot->readSetBegin(_etype347, _size344);
+            uint32_t _i348;
+            for (_i348 = 0; _i348 < _size344; ++_i348)
             {
-              std::string _elem287;
-              xfer += iprot->readString(_elem287);
-              (*(this->success)).insert(_elem287);
+              std::string _elem349;
+              xfer += iprot->readString(_elem349);
+              (*(this->success)).insert(_elem349);
             }
             xfer += iprot->readSetEnd();
           }
@@ -6144,8 +6719,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listIterators_args::~AccumuloProxy_listIterators_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_listIterators_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6194,6 +6775,7 @@
 
 uint32_t AccumuloProxy_listIterators_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_listIterators_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -6209,8 +6791,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listIterators_pargs::~AccumuloProxy_listIterators_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_listIterators_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_listIterators_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -6226,8 +6814,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listIterators_result::~AccumuloProxy_listIterators_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_listIterators_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6250,29 +6844,29 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->success.clear();
-            uint32_t _size288;
-            ::apache::thrift::protocol::TType _ktype289;
-            ::apache::thrift::protocol::TType _vtype290;
-            xfer += iprot->readMapBegin(_ktype289, _vtype290, _size288);
-            uint32_t _i292;
-            for (_i292 = 0; _i292 < _size288; ++_i292)
+            uint32_t _size350;
+            ::apache::thrift::protocol::TType _ktype351;
+            ::apache::thrift::protocol::TType _vtype352;
+            xfer += iprot->readMapBegin(_ktype351, _vtype352, _size350);
+            uint32_t _i354;
+            for (_i354 = 0; _i354 < _size350; ++_i354)
             {
-              std::string _key293;
-              xfer += iprot->readString(_key293);
-              std::set<IteratorScope::type> & _val294 = this->success[_key293];
+              std::string _key355;
+              xfer += iprot->readString(_key355);
+              std::set<IteratorScope::type> & _val356 = this->success[_key355];
               {
-                _val294.clear();
-                uint32_t _size295;
-                ::apache::thrift::protocol::TType _etype298;
-                xfer += iprot->readSetBegin(_etype298, _size295);
-                uint32_t _i299;
-                for (_i299 = 0; _i299 < _size295; ++_i299)
+                _val356.clear();
+                uint32_t _size357;
+                ::apache::thrift::protocol::TType _etype360;
+                xfer += iprot->readSetBegin(_etype360, _size357);
+                uint32_t _i361;
+                for (_i361 = 0; _i361 < _size357; ++_i361)
                 {
-                  IteratorScope::type _elem300;
-                  int32_t ecast301;
-                  xfer += iprot->readI32(ecast301);
-                  _elem300 = (IteratorScope::type)ecast301;
-                  _val294.insert(_elem300);
+                  IteratorScope::type _elem362;
+                  int32_t ecast363;
+                  xfer += iprot->readI32(ecast363);
+                  _elem362 = (IteratorScope::type)ecast363;
+                  _val356.insert(_elem362);
                 }
                 xfer += iprot->readSetEnd();
               }
@@ -6330,16 +6924,16 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
     {
       xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_SET, static_cast<uint32_t>(this->success.size()));
-      std::map<std::string, std::set<IteratorScope::type> > ::const_iterator _iter302;
-      for (_iter302 = this->success.begin(); _iter302 != this->success.end(); ++_iter302)
+      std::map<std::string, std::set<IteratorScope::type> > ::const_iterator _iter364;
+      for (_iter364 = this->success.begin(); _iter364 != this->success.end(); ++_iter364)
       {
-        xfer += oprot->writeString(_iter302->first);
+        xfer += oprot->writeString(_iter364->first);
         {
-          xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(_iter302->second.size()));
-          std::set<IteratorScope::type> ::const_iterator _iter303;
-          for (_iter303 = _iter302->second.begin(); _iter303 != _iter302->second.end(); ++_iter303)
+          xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(_iter364->second.size()));
+          std::set<IteratorScope::type> ::const_iterator _iter365;
+          for (_iter365 = _iter364->second.begin(); _iter365 != _iter364->second.end(); ++_iter365)
           {
-            xfer += oprot->writeI32((int32_t)(*_iter303));
+            xfer += oprot->writeI32((int32_t)(*_iter365));
           }
           xfer += oprot->writeSetEnd();
         }
@@ -6365,8 +6959,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listIterators_presult::~AccumuloProxy_listIterators_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_listIterators_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6389,29 +6989,29 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             (*(this->success)).clear();
-            uint32_t _size304;
-            ::apache::thrift::protocol::TType _ktype305;
-            ::apache::thrift::protocol::TType _vtype306;
-            xfer += iprot->readMapBegin(_ktype305, _vtype306, _size304);
-            uint32_t _i308;
-            for (_i308 = 0; _i308 < _size304; ++_i308)
+            uint32_t _size366;
+            ::apache::thrift::protocol::TType _ktype367;
+            ::apache::thrift::protocol::TType _vtype368;
+            xfer += iprot->readMapBegin(_ktype367, _vtype368, _size366);
+            uint32_t _i370;
+            for (_i370 = 0; _i370 < _size366; ++_i370)
             {
-              std::string _key309;
-              xfer += iprot->readString(_key309);
-              std::set<IteratorScope::type> & _val310 = (*(this->success))[_key309];
+              std::string _key371;
+              xfer += iprot->readString(_key371);
+              std::set<IteratorScope::type> & _val372 = (*(this->success))[_key371];
               {
-                _val310.clear();
-                uint32_t _size311;
-                ::apache::thrift::protocol::TType _etype314;
-                xfer += iprot->readSetBegin(_etype314, _size311);
-                uint32_t _i315;
-                for (_i315 = 0; _i315 < _size311; ++_i315)
+                _val372.clear();
+                uint32_t _size373;
+                ::apache::thrift::protocol::TType _etype376;
+                xfer += iprot->readSetBegin(_etype376, _size373);
+                uint32_t _i377;
+                for (_i377 = 0; _i377 < _size373; ++_i377)
                 {
-                  IteratorScope::type _elem316;
-                  int32_t ecast317;
-                  xfer += iprot->readI32(ecast317);
-                  _elem316 = (IteratorScope::type)ecast317;
-                  _val310.insert(_elem316);
+                  IteratorScope::type _elem378;
+                  int32_t ecast379;
+                  xfer += iprot->readI32(ecast379);
+                  _elem378 = (IteratorScope::type)ecast379;
+                  _val372.insert(_elem378);
                 }
                 xfer += iprot->readSetEnd();
               }
@@ -6459,8 +7059,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listConstraints_args::~AccumuloProxy_listConstraints_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_listConstraints_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6509,6 +7115,7 @@
 
 uint32_t AccumuloProxy_listConstraints_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_listConstraints_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -6524,8 +7131,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listConstraints_pargs::~AccumuloProxy_listConstraints_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_listConstraints_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_listConstraints_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -6541,8 +7154,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listConstraints_result::~AccumuloProxy_listConstraints_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_listConstraints_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6565,17 +7184,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->success.clear();
-            uint32_t _size318;
-            ::apache::thrift::protocol::TType _ktype319;
-            ::apache::thrift::protocol::TType _vtype320;
-            xfer += iprot->readMapBegin(_ktype319, _vtype320, _size318);
-            uint32_t _i322;
-            for (_i322 = 0; _i322 < _size318; ++_i322)
+            uint32_t _size380;
+            ::apache::thrift::protocol::TType _ktype381;
+            ::apache::thrift::protocol::TType _vtype382;
+            xfer += iprot->readMapBegin(_ktype381, _vtype382, _size380);
+            uint32_t _i384;
+            for (_i384 = 0; _i384 < _size380; ++_i384)
             {
-              std::string _key323;
-              xfer += iprot->readString(_key323);
-              int32_t& _val324 = this->success[_key323];
-              xfer += iprot->readI32(_val324);
+              std::string _key385;
+              xfer += iprot->readString(_key385);
+              int32_t& _val386 = this->success[_key385];
+              xfer += iprot->readI32(_val386);
             }
             xfer += iprot->readMapEnd();
           }
@@ -6630,11 +7249,11 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
     {
       xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->success.size()));
-      std::map<std::string, int32_t> ::const_iterator _iter325;
-      for (_iter325 = this->success.begin(); _iter325 != this->success.end(); ++_iter325)
+      std::map<std::string, int32_t> ::const_iterator _iter387;
+      for (_iter387 = this->success.begin(); _iter387 != this->success.end(); ++_iter387)
       {
-        xfer += oprot->writeString(_iter325->first);
-        xfer += oprot->writeI32(_iter325->second);
+        xfer += oprot->writeString(_iter387->first);
+        xfer += oprot->writeI32(_iter387->second);
       }
       xfer += oprot->writeMapEnd();
     }
@@ -6657,8 +7276,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listConstraints_presult::~AccumuloProxy_listConstraints_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_listConstraints_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6681,17 +7306,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             (*(this->success)).clear();
-            uint32_t _size326;
-            ::apache::thrift::protocol::TType _ktype327;
-            ::apache::thrift::protocol::TType _vtype328;
-            xfer += iprot->readMapBegin(_ktype327, _vtype328, _size326);
-            uint32_t _i330;
-            for (_i330 = 0; _i330 < _size326; ++_i330)
+            uint32_t _size388;
+            ::apache::thrift::protocol::TType _ktype389;
+            ::apache::thrift::protocol::TType _vtype390;
+            xfer += iprot->readMapBegin(_ktype389, _vtype390, _size388);
+            uint32_t _i392;
+            for (_i392 = 0; _i392 < _size388; ++_i392)
             {
-              std::string _key331;
-              xfer += iprot->readString(_key331);
-              int32_t& _val332 = (*(this->success))[_key331];
-              xfer += iprot->readI32(_val332);
+              std::string _key393;
+              xfer += iprot->readString(_key393);
+              int32_t& _val394 = (*(this->success))[_key393];
+              xfer += iprot->readI32(_val394);
             }
             xfer += iprot->readMapEnd();
           }
@@ -6736,8 +7361,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_mergeTablets_args::~AccumuloProxy_mergeTablets_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_mergeTablets_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6802,6 +7433,7 @@
 
 uint32_t AccumuloProxy_mergeTablets_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_mergeTablets_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -6825,8 +7457,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_mergeTablets_pargs::~AccumuloProxy_mergeTablets_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_mergeTablets_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_mergeTablets_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -6850,8 +7488,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_mergeTablets_result::~AccumuloProxy_mergeTablets_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_mergeTablets_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6930,8 +7574,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_mergeTablets_presult::~AccumuloProxy_mergeTablets_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_mergeTablets_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -6986,8 +7636,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_offlineTable_args::~AccumuloProxy_offlineTable_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_offlineTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7044,6 +7700,7 @@
 
 uint32_t AccumuloProxy_offlineTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_offlineTable_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -7063,8 +7720,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_offlineTable_pargs::~AccumuloProxy_offlineTable_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_offlineTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_offlineTable_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -7084,8 +7747,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_offlineTable_result::~AccumuloProxy_offlineTable_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_offlineTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7164,8 +7833,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_offlineTable_presult::~AccumuloProxy_offlineTable_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_offlineTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7220,8 +7895,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_onlineTable_args::~AccumuloProxy_onlineTable_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_onlineTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7278,6 +7959,7 @@
 
 uint32_t AccumuloProxy_onlineTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_onlineTable_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -7297,8 +7979,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_onlineTable_pargs::~AccumuloProxy_onlineTable_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_onlineTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_onlineTable_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -7318,8 +8006,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_onlineTable_result::~AccumuloProxy_onlineTable_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_onlineTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7398,8 +8092,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_onlineTable_presult::~AccumuloProxy_onlineTable_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_onlineTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7454,8 +8154,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeConstraint_args::~AccumuloProxy_removeConstraint_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeConstraint_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7512,6 +8218,7 @@
 
 uint32_t AccumuloProxy_removeConstraint_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_removeConstraint_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -7531,8 +8238,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeConstraint_pargs::~AccumuloProxy_removeConstraint_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeConstraint_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_removeConstraint_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -7552,8 +8265,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeConstraint_result::~AccumuloProxy_removeConstraint_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeConstraint_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7632,8 +8351,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeConstraint_presult::~AccumuloProxy_removeConstraint_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeConstraint_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7688,8 +8413,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeIterator_args::~AccumuloProxy_removeIterator_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeIterator_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7736,17 +8467,17 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->scopes.clear();
-            uint32_t _size333;
-            ::apache::thrift::protocol::TType _etype336;
-            xfer += iprot->readSetBegin(_etype336, _size333);
-            uint32_t _i337;
-            for (_i337 = 0; _i337 < _size333; ++_i337)
+            uint32_t _size395;
+            ::apache::thrift::protocol::TType _etype398;
+            xfer += iprot->readSetBegin(_etype398, _size395);
+            uint32_t _i399;
+            for (_i399 = 0; _i399 < _size395; ++_i399)
             {
-              IteratorScope::type _elem338;
-              int32_t ecast339;
-              xfer += iprot->readI32(ecast339);
-              _elem338 = (IteratorScope::type)ecast339;
-              this->scopes.insert(_elem338);
+              IteratorScope::type _elem400;
+              int32_t ecast401;
+              xfer += iprot->readI32(ecast401);
+              _elem400 = (IteratorScope::type)ecast401;
+              this->scopes.insert(_elem400);
             }
             xfer += iprot->readSetEnd();
           }
@@ -7769,6 +8500,7 @@
 
 uint32_t AccumuloProxy_removeIterator_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_removeIterator_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -7786,10 +8518,10 @@
   xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
-    std::set<IteratorScope::type> ::const_iterator _iter340;
-    for (_iter340 = this->scopes.begin(); _iter340 != this->scopes.end(); ++_iter340)
+    std::set<IteratorScope::type> ::const_iterator _iter402;
+    for (_iter402 = this->scopes.begin(); _iter402 != this->scopes.end(); ++_iter402)
     {
-      xfer += oprot->writeI32((int32_t)(*_iter340));
+      xfer += oprot->writeI32((int32_t)(*_iter402));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -7800,8 +8532,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeIterator_pargs::~AccumuloProxy_removeIterator_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeIterator_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_removeIterator_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -7819,10 +8557,10 @@
   xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
-    std::set<IteratorScope::type> ::const_iterator _iter341;
-    for (_iter341 = (*(this->scopes)).begin(); _iter341 != (*(this->scopes)).end(); ++_iter341)
+    std::set<IteratorScope::type> ::const_iterator _iter403;
+    for (_iter403 = (*(this->scopes)).begin(); _iter403 != (*(this->scopes)).end(); ++_iter403)
     {
-      xfer += oprot->writeI32((int32_t)(*_iter341));
+      xfer += oprot->writeI32((int32_t)(*_iter403));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -7833,8 +8571,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeIterator_result::~AccumuloProxy_removeIterator_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeIterator_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7913,8 +8657,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeIterator_presult::~AccumuloProxy_removeIterator_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeIterator_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -7969,8 +8719,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeTableProperty_args::~AccumuloProxy_removeTableProperty_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeTableProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8027,6 +8783,7 @@
 
 uint32_t AccumuloProxy_removeTableProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_removeTableProperty_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -8046,8 +8803,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeTableProperty_pargs::~AccumuloProxy_removeTableProperty_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeTableProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_removeTableProperty_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -8067,8 +8830,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeTableProperty_result::~AccumuloProxy_removeTableProperty_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeTableProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8147,8 +8916,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeTableProperty_presult::~AccumuloProxy_removeTableProperty_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeTableProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8203,8 +8978,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_renameTable_args::~AccumuloProxy_renameTable_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_renameTable_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8261,6 +9042,7 @@
 
 uint32_t AccumuloProxy_renameTable_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_renameTable_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -8280,8 +9062,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_renameTable_pargs::~AccumuloProxy_renameTable_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_renameTable_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_renameTable_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -8301,8 +9089,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_renameTable_result::~AccumuloProxy_renameTable_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_renameTable_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8393,8 +9187,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_renameTable_presult::~AccumuloProxy_renameTable_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_renameTable_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8457,8 +9257,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setLocalityGroups_args::~AccumuloProxy_setLocalityGroups_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_setLocalityGroups_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8497,27 +9303,27 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->groups.clear();
-            uint32_t _size342;
-            ::apache::thrift::protocol::TType _ktype343;
-            ::apache::thrift::protocol::TType _vtype344;
-            xfer += iprot->readMapBegin(_ktype343, _vtype344, _size342);
-            uint32_t _i346;
-            for (_i346 = 0; _i346 < _size342; ++_i346)
+            uint32_t _size404;
+            ::apache::thrift::protocol::TType _ktype405;
+            ::apache::thrift::protocol::TType _vtype406;
+            xfer += iprot->readMapBegin(_ktype405, _vtype406, _size404);
+            uint32_t _i408;
+            for (_i408 = 0; _i408 < _size404; ++_i408)
             {
-              std::string _key347;
-              xfer += iprot->readString(_key347);
-              std::set<std::string> & _val348 = this->groups[_key347];
+              std::string _key409;
+              xfer += iprot->readString(_key409);
+              std::set<std::string> & _val410 = this->groups[_key409];
               {
-                _val348.clear();
-                uint32_t _size349;
-                ::apache::thrift::protocol::TType _etype352;
-                xfer += iprot->readSetBegin(_etype352, _size349);
-                uint32_t _i353;
-                for (_i353 = 0; _i353 < _size349; ++_i353)
+                _val410.clear();
+                uint32_t _size411;
+                ::apache::thrift::protocol::TType _etype414;
+                xfer += iprot->readSetBegin(_etype414, _size411);
+                uint32_t _i415;
+                for (_i415 = 0; _i415 < _size411; ++_i415)
                 {
-                  std::string _elem354;
-                  xfer += iprot->readString(_elem354);
-                  _val348.insert(_elem354);
+                  std::string _elem416;
+                  xfer += iprot->readString(_elem416);
+                  _val410.insert(_elem416);
                 }
                 xfer += iprot->readSetEnd();
               }
@@ -8543,6 +9349,7 @@
 
 uint32_t AccumuloProxy_setLocalityGroups_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_setLocalityGroups_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -8556,16 +9363,16 @@
   xfer += oprot->writeFieldBegin("groups", ::apache::thrift::protocol::T_MAP, 3);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_SET, static_cast<uint32_t>(this->groups.size()));
-    std::map<std::string, std::set<std::string> > ::const_iterator _iter355;
-    for (_iter355 = this->groups.begin(); _iter355 != this->groups.end(); ++_iter355)
+    std::map<std::string, std::set<std::string> > ::const_iterator _iter417;
+    for (_iter417 = this->groups.begin(); _iter417 != this->groups.end(); ++_iter417)
     {
-      xfer += oprot->writeString(_iter355->first);
+      xfer += oprot->writeString(_iter417->first);
       {
-        xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(_iter355->second.size()));
-        std::set<std::string> ::const_iterator _iter356;
-        for (_iter356 = _iter355->second.begin(); _iter356 != _iter355->second.end(); ++_iter356)
+        xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(_iter417->second.size()));
+        std::set<std::string> ::const_iterator _iter418;
+        for (_iter418 = _iter417->second.begin(); _iter418 != _iter417->second.end(); ++_iter418)
         {
-          xfer += oprot->writeString((*_iter356));
+          xfer += oprot->writeString((*_iter418));
         }
         xfer += oprot->writeSetEnd();
       }
@@ -8579,8 +9386,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setLocalityGroups_pargs::~AccumuloProxy_setLocalityGroups_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_setLocalityGroups_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_setLocalityGroups_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -8594,16 +9407,16 @@
   xfer += oprot->writeFieldBegin("groups", ::apache::thrift::protocol::T_MAP, 3);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_SET, static_cast<uint32_t>((*(this->groups)).size()));
-    std::map<std::string, std::set<std::string> > ::const_iterator _iter357;
-    for (_iter357 = (*(this->groups)).begin(); _iter357 != (*(this->groups)).end(); ++_iter357)
+    std::map<std::string, std::set<std::string> > ::const_iterator _iter419;
+    for (_iter419 = (*(this->groups)).begin(); _iter419 != (*(this->groups)).end(); ++_iter419)
     {
-      xfer += oprot->writeString(_iter357->first);
+      xfer += oprot->writeString(_iter419->first);
       {
-        xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(_iter357->second.size()));
-        std::set<std::string> ::const_iterator _iter358;
-        for (_iter358 = _iter357->second.begin(); _iter358 != _iter357->second.end(); ++_iter358)
+        xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(_iter419->second.size()));
+        std::set<std::string> ::const_iterator _iter420;
+        for (_iter420 = _iter419->second.begin(); _iter420 != _iter419->second.end(); ++_iter420)
         {
-          xfer += oprot->writeString((*_iter358));
+          xfer += oprot->writeString((*_iter420));
         }
         xfer += oprot->writeSetEnd();
       }
@@ -8617,8 +9430,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setLocalityGroups_result::~AccumuloProxy_setLocalityGroups_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_setLocalityGroups_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8697,8 +9516,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setLocalityGroups_presult::~AccumuloProxy_setLocalityGroups_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_setLocalityGroups_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8753,8 +9578,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setTableProperty_args::~AccumuloProxy_setTableProperty_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_setTableProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8819,6 +9650,7 @@
 
 uint32_t AccumuloProxy_setTableProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_setTableProperty_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -8842,8 +9674,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setTableProperty_pargs::~AccumuloProxy_setTableProperty_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_setTableProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_setTableProperty_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -8867,8 +9705,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setTableProperty_result::~AccumuloProxy_setTableProperty_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_setTableProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -8947,8 +9791,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setTableProperty_presult::~AccumuloProxy_setTableProperty_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_setTableProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9003,8 +9853,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_splitRangeByTablets_args::~AccumuloProxy_splitRangeByTablets_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_splitRangeByTablets_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9069,6 +9925,7 @@
 
 uint32_t AccumuloProxy_splitRangeByTablets_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_splitRangeByTablets_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -9092,8 +9949,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_splitRangeByTablets_pargs::~AccumuloProxy_splitRangeByTablets_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_splitRangeByTablets_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_splitRangeByTablets_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -9117,8 +9980,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_splitRangeByTablets_result::~AccumuloProxy_splitRangeByTablets_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_splitRangeByTablets_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9141,15 +10010,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->success.clear();
-            uint32_t _size359;
-            ::apache::thrift::protocol::TType _etype362;
-            xfer += iprot->readSetBegin(_etype362, _size359);
-            uint32_t _i363;
-            for (_i363 = 0; _i363 < _size359; ++_i363)
+            uint32_t _size421;
+            ::apache::thrift::protocol::TType _etype424;
+            xfer += iprot->readSetBegin(_etype424, _size421);
+            uint32_t _i425;
+            for (_i425 = 0; _i425 < _size421; ++_i425)
             {
-              Range _elem364;
-              xfer += _elem364.read(iprot);
-              this->success.insert(_elem364);
+              Range _elem426;
+              xfer += _elem426.read(iprot);
+              this->success.insert(_elem426);
             }
             xfer += iprot->readSetEnd();
           }
@@ -9204,10 +10073,10 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_SET, 0);
     {
       xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
-      std::set<Range> ::const_iterator _iter365;
-      for (_iter365 = this->success.begin(); _iter365 != this->success.end(); ++_iter365)
+      std::set<Range> ::const_iterator _iter427;
+      for (_iter427 = this->success.begin(); _iter427 != this->success.end(); ++_iter427)
       {
-        xfer += (*_iter365).write(oprot);
+        xfer += (*_iter427).write(oprot);
       }
       xfer += oprot->writeSetEnd();
     }
@@ -9230,8 +10099,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_splitRangeByTablets_presult::~AccumuloProxy_splitRangeByTablets_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_splitRangeByTablets_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9254,15 +10129,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             (*(this->success)).clear();
-            uint32_t _size366;
-            ::apache::thrift::protocol::TType _etype369;
-            xfer += iprot->readSetBegin(_etype369, _size366);
-            uint32_t _i370;
-            for (_i370 = 0; _i370 < _size366; ++_i370)
+            uint32_t _size428;
+            ::apache::thrift::protocol::TType _etype431;
+            xfer += iprot->readSetBegin(_etype431, _size428);
+            uint32_t _i432;
+            for (_i432 = 0; _i432 < _size428; ++_i432)
             {
-              Range _elem371;
-              xfer += _elem371.read(iprot);
-              (*(this->success)).insert(_elem371);
+              Range _elem433;
+              xfer += _elem433.read(iprot);
+              (*(this->success)).insert(_elem433);
             }
             xfer += iprot->readSetEnd();
           }
@@ -9307,8 +10182,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_tableExists_args::~AccumuloProxy_tableExists_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_tableExists_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9357,6 +10238,7 @@
 
 uint32_t AccumuloProxy_tableExists_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_tableExists_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -9372,8 +10254,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_tableExists_pargs::~AccumuloProxy_tableExists_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_tableExists_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_tableExists_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -9389,8 +10277,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_tableExists_result::~AccumuloProxy_tableExists_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_tableExists_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9445,8 +10339,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_tableExists_presult::~AccumuloProxy_tableExists_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_tableExists_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9485,8 +10385,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_tableIdMap_args::~AccumuloProxy_tableIdMap_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_tableIdMap_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9527,6 +10433,7 @@
 
 uint32_t AccumuloProxy_tableIdMap_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_tableIdMap_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -9538,8 +10445,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_tableIdMap_pargs::~AccumuloProxy_tableIdMap_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_tableIdMap_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_tableIdMap_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -9551,8 +10464,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_tableIdMap_result::~AccumuloProxy_tableIdMap_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_tableIdMap_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9575,17 +10494,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->success.clear();
-            uint32_t _size372;
-            ::apache::thrift::protocol::TType _ktype373;
-            ::apache::thrift::protocol::TType _vtype374;
-            xfer += iprot->readMapBegin(_ktype373, _vtype374, _size372);
-            uint32_t _i376;
-            for (_i376 = 0; _i376 < _size372; ++_i376)
+            uint32_t _size434;
+            ::apache::thrift::protocol::TType _ktype435;
+            ::apache::thrift::protocol::TType _vtype436;
+            xfer += iprot->readMapBegin(_ktype435, _vtype436, _size434);
+            uint32_t _i438;
+            for (_i438 = 0; _i438 < _size434; ++_i438)
             {
-              std::string _key377;
-              xfer += iprot->readString(_key377);
-              std::string& _val378 = this->success[_key377];
-              xfer += iprot->readString(_val378);
+              std::string _key439;
+              xfer += iprot->readString(_key439);
+              std::string& _val440 = this->success[_key439];
+              xfer += iprot->readString(_val440);
             }
             xfer += iprot->readMapEnd();
           }
@@ -9616,11 +10535,11 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
     {
       xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
-      std::map<std::string, std::string> ::const_iterator _iter379;
-      for (_iter379 = this->success.begin(); _iter379 != this->success.end(); ++_iter379)
+      std::map<std::string, std::string> ::const_iterator _iter441;
+      for (_iter441 = this->success.begin(); _iter441 != this->success.end(); ++_iter441)
       {
-        xfer += oprot->writeString(_iter379->first);
-        xfer += oprot->writeString(_iter379->second);
+        xfer += oprot->writeString(_iter441->first);
+        xfer += oprot->writeString(_iter441->second);
       }
       xfer += oprot->writeMapEnd();
     }
@@ -9631,8 +10550,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_tableIdMap_presult::~AccumuloProxy_tableIdMap_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_tableIdMap_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9655,17 +10580,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             (*(this->success)).clear();
-            uint32_t _size380;
-            ::apache::thrift::protocol::TType _ktype381;
-            ::apache::thrift::protocol::TType _vtype382;
-            xfer += iprot->readMapBegin(_ktype381, _vtype382, _size380);
-            uint32_t _i384;
-            for (_i384 = 0; _i384 < _size380; ++_i384)
+            uint32_t _size442;
+            ::apache::thrift::protocol::TType _ktype443;
+            ::apache::thrift::protocol::TType _vtype444;
+            xfer += iprot->readMapBegin(_ktype443, _vtype444, _size442);
+            uint32_t _i446;
+            for (_i446 = 0; _i446 < _size442; ++_i446)
             {
-              std::string _key385;
-              xfer += iprot->readString(_key385);
-              std::string& _val386 = (*(this->success))[_key385];
-              xfer += iprot->readString(_val386);
+              std::string _key447;
+              xfer += iprot->readString(_key447);
+              std::string& _val448 = (*(this->success))[_key447];
+              xfer += iprot->readString(_val448);
             }
             xfer += iprot->readMapEnd();
           }
@@ -9686,8 +10611,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_testTableClassLoad_args::~AccumuloProxy_testTableClassLoad_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_testTableClassLoad_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9752,6 +10683,7 @@
 
 uint32_t AccumuloProxy_testTableClassLoad_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_testTableClassLoad_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -9775,8 +10707,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_testTableClassLoad_pargs::~AccumuloProxy_testTableClassLoad_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_testTableClassLoad_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_testTableClassLoad_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -9800,8 +10738,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_testTableClassLoad_result::~AccumuloProxy_testTableClassLoad_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_testTableClassLoad_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9892,8 +10836,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_testTableClassLoad_presult::~AccumuloProxy_testTableClassLoad_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_testTableClassLoad_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -9956,8 +10906,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_pingTabletServer_args::~AccumuloProxy_pingTabletServer_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_pingTabletServer_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10006,6 +10962,7 @@
 
 uint32_t AccumuloProxy_pingTabletServer_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_pingTabletServer_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -10021,8 +10978,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_pingTabletServer_pargs::~AccumuloProxy_pingTabletServer_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_pingTabletServer_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_pingTabletServer_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -10038,8 +11001,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_pingTabletServer_result::~AccumuloProxy_pingTabletServer_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_pingTabletServer_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10106,8 +11075,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_pingTabletServer_presult::~AccumuloProxy_pingTabletServer_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_pingTabletServer_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10154,8 +11129,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getActiveScans_args::~AccumuloProxy_getActiveScans_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getActiveScans_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10204,6 +11185,7 @@
 
 uint32_t AccumuloProxy_getActiveScans_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getActiveScans_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -10219,8 +11201,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getActiveScans_pargs::~AccumuloProxy_getActiveScans_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getActiveScans_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getActiveScans_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -10236,8 +11224,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getActiveScans_result::~AccumuloProxy_getActiveScans_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getActiveScans_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10260,14 +11254,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->success.clear();
-            uint32_t _size387;
-            ::apache::thrift::protocol::TType _etype390;
-            xfer += iprot->readListBegin(_etype390, _size387);
-            this->success.resize(_size387);
-            uint32_t _i391;
-            for (_i391 = 0; _i391 < _size387; ++_i391)
+            uint32_t _size449;
+            ::apache::thrift::protocol::TType _etype452;
+            xfer += iprot->readListBegin(_etype452, _size449);
+            this->success.resize(_size449);
+            uint32_t _i453;
+            for (_i453 = 0; _i453 < _size449; ++_i453)
             {
-              xfer += this->success[_i391].read(iprot);
+              xfer += this->success[_i453].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -10314,10 +11308,10 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
-      std::vector<ActiveScan> ::const_iterator _iter392;
-      for (_iter392 = this->success.begin(); _iter392 != this->success.end(); ++_iter392)
+      std::vector<ActiveScan> ::const_iterator _iter454;
+      for (_iter454 = this->success.begin(); _iter454 != this->success.end(); ++_iter454)
       {
-        xfer += (*_iter392).write(oprot);
+        xfer += (*_iter454).write(oprot);
       }
       xfer += oprot->writeListEnd();
     }
@@ -10336,8 +11330,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getActiveScans_presult::~AccumuloProxy_getActiveScans_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getActiveScans_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10360,14 +11360,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             (*(this->success)).clear();
-            uint32_t _size393;
-            ::apache::thrift::protocol::TType _etype396;
-            xfer += iprot->readListBegin(_etype396, _size393);
-            (*(this->success)).resize(_size393);
-            uint32_t _i397;
-            for (_i397 = 0; _i397 < _size393; ++_i397)
+            uint32_t _size455;
+            ::apache::thrift::protocol::TType _etype458;
+            xfer += iprot->readListBegin(_etype458, _size455);
+            (*(this->success)).resize(_size455);
+            uint32_t _i459;
+            for (_i459 = 0; _i459 < _size455; ++_i459)
             {
-              xfer += (*(this->success))[_i397].read(iprot);
+              xfer += (*(this->success))[_i459].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -10404,8 +11404,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getActiveCompactions_args::~AccumuloProxy_getActiveCompactions_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getActiveCompactions_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10454,6 +11460,7 @@
 
 uint32_t AccumuloProxy_getActiveCompactions_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getActiveCompactions_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -10469,8 +11476,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getActiveCompactions_pargs::~AccumuloProxy_getActiveCompactions_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getActiveCompactions_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getActiveCompactions_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -10486,8 +11499,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getActiveCompactions_result::~AccumuloProxy_getActiveCompactions_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getActiveCompactions_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10510,14 +11529,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->success.clear();
-            uint32_t _size398;
-            ::apache::thrift::protocol::TType _etype401;
-            xfer += iprot->readListBegin(_etype401, _size398);
-            this->success.resize(_size398);
-            uint32_t _i402;
-            for (_i402 = 0; _i402 < _size398; ++_i402)
+            uint32_t _size460;
+            ::apache::thrift::protocol::TType _etype463;
+            xfer += iprot->readListBegin(_etype463, _size460);
+            this->success.resize(_size460);
+            uint32_t _i464;
+            for (_i464 = 0; _i464 < _size460; ++_i464)
             {
-              xfer += this->success[_i402].read(iprot);
+              xfer += this->success[_i464].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -10564,10 +11583,10 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
-      std::vector<ActiveCompaction> ::const_iterator _iter403;
-      for (_iter403 = this->success.begin(); _iter403 != this->success.end(); ++_iter403)
+      std::vector<ActiveCompaction> ::const_iterator _iter465;
+      for (_iter465 = this->success.begin(); _iter465 != this->success.end(); ++_iter465)
       {
-        xfer += (*_iter403).write(oprot);
+        xfer += (*_iter465).write(oprot);
       }
       xfer += oprot->writeListEnd();
     }
@@ -10586,8 +11605,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getActiveCompactions_presult::~AccumuloProxy_getActiveCompactions_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getActiveCompactions_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10610,14 +11635,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             (*(this->success)).clear();
-            uint32_t _size404;
-            ::apache::thrift::protocol::TType _etype407;
-            xfer += iprot->readListBegin(_etype407, _size404);
-            (*(this->success)).resize(_size404);
-            uint32_t _i408;
-            for (_i408 = 0; _i408 < _size404; ++_i408)
+            uint32_t _size466;
+            ::apache::thrift::protocol::TType _etype469;
+            xfer += iprot->readListBegin(_etype469, _size466);
+            (*(this->success)).resize(_size466);
+            uint32_t _i470;
+            for (_i470 = 0; _i470 < _size466; ++_i470)
             {
-              xfer += (*(this->success))[_i408].read(iprot);
+              xfer += (*(this->success))[_i470].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -10654,8 +11679,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getSiteConfiguration_args::~AccumuloProxy_getSiteConfiguration_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getSiteConfiguration_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10696,6 +11727,7 @@
 
 uint32_t AccumuloProxy_getSiteConfiguration_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getSiteConfiguration_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -10707,8 +11739,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getSiteConfiguration_pargs::~AccumuloProxy_getSiteConfiguration_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getSiteConfiguration_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getSiteConfiguration_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -10720,8 +11758,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getSiteConfiguration_result::~AccumuloProxy_getSiteConfiguration_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getSiteConfiguration_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10744,17 +11788,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->success.clear();
-            uint32_t _size409;
-            ::apache::thrift::protocol::TType _ktype410;
-            ::apache::thrift::protocol::TType _vtype411;
-            xfer += iprot->readMapBegin(_ktype410, _vtype411, _size409);
-            uint32_t _i413;
-            for (_i413 = 0; _i413 < _size409; ++_i413)
+            uint32_t _size471;
+            ::apache::thrift::protocol::TType _ktype472;
+            ::apache::thrift::protocol::TType _vtype473;
+            xfer += iprot->readMapBegin(_ktype472, _vtype473, _size471);
+            uint32_t _i475;
+            for (_i475 = 0; _i475 < _size471; ++_i475)
             {
-              std::string _key414;
-              xfer += iprot->readString(_key414);
-              std::string& _val415 = this->success[_key414];
-              xfer += iprot->readString(_val415);
+              std::string _key476;
+              xfer += iprot->readString(_key476);
+              std::string& _val477 = this->success[_key476];
+              xfer += iprot->readString(_val477);
             }
             xfer += iprot->readMapEnd();
           }
@@ -10801,11 +11845,11 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
     {
       xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
-      std::map<std::string, std::string> ::const_iterator _iter416;
-      for (_iter416 = this->success.begin(); _iter416 != this->success.end(); ++_iter416)
+      std::map<std::string, std::string> ::const_iterator _iter478;
+      for (_iter478 = this->success.begin(); _iter478 != this->success.end(); ++_iter478)
       {
-        xfer += oprot->writeString(_iter416->first);
-        xfer += oprot->writeString(_iter416->second);
+        xfer += oprot->writeString(_iter478->first);
+        xfer += oprot->writeString(_iter478->second);
       }
       xfer += oprot->writeMapEnd();
     }
@@ -10824,8 +11868,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getSiteConfiguration_presult::~AccumuloProxy_getSiteConfiguration_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getSiteConfiguration_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10848,17 +11898,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             (*(this->success)).clear();
-            uint32_t _size417;
-            ::apache::thrift::protocol::TType _ktype418;
-            ::apache::thrift::protocol::TType _vtype419;
-            xfer += iprot->readMapBegin(_ktype418, _vtype419, _size417);
-            uint32_t _i421;
-            for (_i421 = 0; _i421 < _size417; ++_i421)
+            uint32_t _size479;
+            ::apache::thrift::protocol::TType _ktype480;
+            ::apache::thrift::protocol::TType _vtype481;
+            xfer += iprot->readMapBegin(_ktype480, _vtype481, _size479);
+            uint32_t _i483;
+            for (_i483 = 0; _i483 < _size479; ++_i483)
             {
-              std::string _key422;
-              xfer += iprot->readString(_key422);
-              std::string& _val423 = (*(this->success))[_key422];
-              xfer += iprot->readString(_val423);
+              std::string _key484;
+              xfer += iprot->readString(_key484);
+              std::string& _val485 = (*(this->success))[_key484];
+              xfer += iprot->readString(_val485);
             }
             xfer += iprot->readMapEnd();
           }
@@ -10895,8 +11945,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getSystemConfiguration_args::~AccumuloProxy_getSystemConfiguration_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getSystemConfiguration_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10937,6 +11993,7 @@
 
 uint32_t AccumuloProxy_getSystemConfiguration_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getSystemConfiguration_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -10948,8 +12005,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getSystemConfiguration_pargs::~AccumuloProxy_getSystemConfiguration_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getSystemConfiguration_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getSystemConfiguration_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -10961,8 +12024,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getSystemConfiguration_result::~AccumuloProxy_getSystemConfiguration_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getSystemConfiguration_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -10985,17 +12054,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->success.clear();
-            uint32_t _size424;
-            ::apache::thrift::protocol::TType _ktype425;
-            ::apache::thrift::protocol::TType _vtype426;
-            xfer += iprot->readMapBegin(_ktype425, _vtype426, _size424);
-            uint32_t _i428;
-            for (_i428 = 0; _i428 < _size424; ++_i428)
+            uint32_t _size486;
+            ::apache::thrift::protocol::TType _ktype487;
+            ::apache::thrift::protocol::TType _vtype488;
+            xfer += iprot->readMapBegin(_ktype487, _vtype488, _size486);
+            uint32_t _i490;
+            for (_i490 = 0; _i490 < _size486; ++_i490)
             {
-              std::string _key429;
-              xfer += iprot->readString(_key429);
-              std::string& _val430 = this->success[_key429];
-              xfer += iprot->readString(_val430);
+              std::string _key491;
+              xfer += iprot->readString(_key491);
+              std::string& _val492 = this->success[_key491];
+              xfer += iprot->readString(_val492);
             }
             xfer += iprot->readMapEnd();
           }
@@ -11042,11 +12111,11 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
     {
       xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
-      std::map<std::string, std::string> ::const_iterator _iter431;
-      for (_iter431 = this->success.begin(); _iter431 != this->success.end(); ++_iter431)
+      std::map<std::string, std::string> ::const_iterator _iter493;
+      for (_iter493 = this->success.begin(); _iter493 != this->success.end(); ++_iter493)
       {
-        xfer += oprot->writeString(_iter431->first);
-        xfer += oprot->writeString(_iter431->second);
+        xfer += oprot->writeString(_iter493->first);
+        xfer += oprot->writeString(_iter493->second);
       }
       xfer += oprot->writeMapEnd();
     }
@@ -11065,8 +12134,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getSystemConfiguration_presult::~AccumuloProxy_getSystemConfiguration_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getSystemConfiguration_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11089,17 +12164,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             (*(this->success)).clear();
-            uint32_t _size432;
-            ::apache::thrift::protocol::TType _ktype433;
-            ::apache::thrift::protocol::TType _vtype434;
-            xfer += iprot->readMapBegin(_ktype433, _vtype434, _size432);
-            uint32_t _i436;
-            for (_i436 = 0; _i436 < _size432; ++_i436)
+            uint32_t _size494;
+            ::apache::thrift::protocol::TType _ktype495;
+            ::apache::thrift::protocol::TType _vtype496;
+            xfer += iprot->readMapBegin(_ktype495, _vtype496, _size494);
+            uint32_t _i498;
+            for (_i498 = 0; _i498 < _size494; ++_i498)
             {
-              std::string _key437;
-              xfer += iprot->readString(_key437);
-              std::string& _val438 = (*(this->success))[_key437];
-              xfer += iprot->readString(_val438);
+              std::string _key499;
+              xfer += iprot->readString(_key499);
+              std::string& _val500 = (*(this->success))[_key499];
+              xfer += iprot->readString(_val500);
             }
             xfer += iprot->readMapEnd();
           }
@@ -11136,8 +12211,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getTabletServers_args::~AccumuloProxy_getTabletServers_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getTabletServers_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11178,6 +12259,7 @@
 
 uint32_t AccumuloProxy_getTabletServers_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getTabletServers_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -11189,8 +12271,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getTabletServers_pargs::~AccumuloProxy_getTabletServers_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getTabletServers_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getTabletServers_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -11202,8 +12290,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getTabletServers_result::~AccumuloProxy_getTabletServers_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getTabletServers_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11226,14 +12320,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->success.clear();
-            uint32_t _size439;
-            ::apache::thrift::protocol::TType _etype442;
-            xfer += iprot->readListBegin(_etype442, _size439);
-            this->success.resize(_size439);
-            uint32_t _i443;
-            for (_i443 = 0; _i443 < _size439; ++_i443)
+            uint32_t _size501;
+            ::apache::thrift::protocol::TType _etype504;
+            xfer += iprot->readListBegin(_etype504, _size501);
+            this->success.resize(_size501);
+            uint32_t _i505;
+            for (_i505 = 0; _i505 < _size501; ++_i505)
             {
-              xfer += iprot->readString(this->success[_i443]);
+              xfer += iprot->readString(this->success[_i505]);
             }
             xfer += iprot->readListEnd();
           }
@@ -11264,10 +12358,10 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
-      std::vector<std::string> ::const_iterator _iter444;
-      for (_iter444 = this->success.begin(); _iter444 != this->success.end(); ++_iter444)
+      std::vector<std::string> ::const_iterator _iter506;
+      for (_iter506 = this->success.begin(); _iter506 != this->success.end(); ++_iter506)
       {
-        xfer += oprot->writeString((*_iter444));
+        xfer += oprot->writeString((*_iter506));
       }
       xfer += oprot->writeListEnd();
     }
@@ -11278,8 +12372,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getTabletServers_presult::~AccumuloProxy_getTabletServers_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getTabletServers_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11302,14 +12402,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             (*(this->success)).clear();
-            uint32_t _size445;
-            ::apache::thrift::protocol::TType _etype448;
-            xfer += iprot->readListBegin(_etype448, _size445);
-            (*(this->success)).resize(_size445);
-            uint32_t _i449;
-            for (_i449 = 0; _i449 < _size445; ++_i449)
+            uint32_t _size507;
+            ::apache::thrift::protocol::TType _etype510;
+            xfer += iprot->readListBegin(_etype510, _size507);
+            (*(this->success)).resize(_size507);
+            uint32_t _i511;
+            for (_i511 = 0; _i511 < _size507; ++_i511)
             {
-              xfer += iprot->readString((*(this->success))[_i449]);
+              xfer += iprot->readString((*(this->success))[_i511]);
             }
             xfer += iprot->readListEnd();
           }
@@ -11330,8 +12430,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeProperty_args::~AccumuloProxy_removeProperty_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11380,6 +12486,7 @@
 
 uint32_t AccumuloProxy_removeProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_removeProperty_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -11395,8 +12502,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeProperty_pargs::~AccumuloProxy_removeProperty_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_removeProperty_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -11412,8 +12525,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeProperty_result::~AccumuloProxy_removeProperty_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11480,8 +12599,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_removeProperty_presult::~AccumuloProxy_removeProperty_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_removeProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11528,8 +12653,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setProperty_args::~AccumuloProxy_setProperty_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_setProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11586,6 +12717,7 @@
 
 uint32_t AccumuloProxy_setProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_setProperty_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -11605,8 +12737,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setProperty_pargs::~AccumuloProxy_setProperty_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_setProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_setProperty_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -11626,8 +12764,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setProperty_result::~AccumuloProxy_setProperty_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_setProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11694,8 +12838,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_setProperty_presult::~AccumuloProxy_setProperty_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_setProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11742,8 +12892,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_testClassLoad_args::~AccumuloProxy_testClassLoad_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_testClassLoad_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11800,6 +12956,7 @@
 
 uint32_t AccumuloProxy_testClassLoad_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_testClassLoad_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -11819,8 +12976,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_testClassLoad_pargs::~AccumuloProxy_testClassLoad_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_testClassLoad_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_testClassLoad_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -11840,8 +13003,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_testClassLoad_result::~AccumuloProxy_testClassLoad_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_testClassLoad_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11920,8 +13089,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_testClassLoad_presult::~AccumuloProxy_testClassLoad_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_testClassLoad_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -11976,8 +13151,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_authenticateUser_args::~AccumuloProxy_authenticateUser_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_authenticateUser_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12016,17 +13197,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->properties.clear();
-            uint32_t _size450;
-            ::apache::thrift::protocol::TType _ktype451;
-            ::apache::thrift::protocol::TType _vtype452;
-            xfer += iprot->readMapBegin(_ktype451, _vtype452, _size450);
-            uint32_t _i454;
-            for (_i454 = 0; _i454 < _size450; ++_i454)
+            uint32_t _size512;
+            ::apache::thrift::protocol::TType _ktype513;
+            ::apache::thrift::protocol::TType _vtype514;
+            xfer += iprot->readMapBegin(_ktype513, _vtype514, _size512);
+            uint32_t _i516;
+            for (_i516 = 0; _i516 < _size512; ++_i516)
             {
-              std::string _key455;
-              xfer += iprot->readString(_key455);
-              std::string& _val456 = this->properties[_key455];
-              xfer += iprot->readString(_val456);
+              std::string _key517;
+              xfer += iprot->readString(_key517);
+              std::string& _val518 = this->properties[_key517];
+              xfer += iprot->readString(_val518);
             }
             xfer += iprot->readMapEnd();
           }
@@ -12049,6 +13230,7 @@
 
 uint32_t AccumuloProxy_authenticateUser_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_authenticateUser_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -12062,11 +13244,11 @@
   xfer += oprot->writeFieldBegin("properties", ::apache::thrift::protocol::T_MAP, 3);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->properties.size()));
-    std::map<std::string, std::string> ::const_iterator _iter457;
-    for (_iter457 = this->properties.begin(); _iter457 != this->properties.end(); ++_iter457)
+    std::map<std::string, std::string> ::const_iterator _iter519;
+    for (_iter519 = this->properties.begin(); _iter519 != this->properties.end(); ++_iter519)
     {
-      xfer += oprot->writeString(_iter457->first);
-      xfer += oprot->writeString(_iter457->second);
+      xfer += oprot->writeString(_iter519->first);
+      xfer += oprot->writeString(_iter519->second);
     }
     xfer += oprot->writeMapEnd();
   }
@@ -12077,8 +13259,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_authenticateUser_pargs::~AccumuloProxy_authenticateUser_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_authenticateUser_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_authenticateUser_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -12092,11 +13280,11 @@
   xfer += oprot->writeFieldBegin("properties", ::apache::thrift::protocol::T_MAP, 3);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->properties)).size()));
-    std::map<std::string, std::string> ::const_iterator _iter458;
-    for (_iter458 = (*(this->properties)).begin(); _iter458 != (*(this->properties)).end(); ++_iter458)
+    std::map<std::string, std::string> ::const_iterator _iter520;
+    for (_iter520 = (*(this->properties)).begin(); _iter520 != (*(this->properties)).end(); ++_iter520)
     {
-      xfer += oprot->writeString(_iter458->first);
-      xfer += oprot->writeString(_iter458->second);
+      xfer += oprot->writeString(_iter520->first);
+      xfer += oprot->writeString(_iter520->second);
     }
     xfer += oprot->writeMapEnd();
   }
@@ -12107,8 +13295,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_authenticateUser_result::~AccumuloProxy_authenticateUser_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_authenticateUser_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12187,8 +13381,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_authenticateUser_presult::~AccumuloProxy_authenticateUser_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_authenticateUser_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12243,8 +13443,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_changeUserAuthorizations_args::~AccumuloProxy_changeUserAuthorizations_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_changeUserAuthorizations_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12283,15 +13489,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->authorizations.clear();
-            uint32_t _size459;
-            ::apache::thrift::protocol::TType _etype462;
-            xfer += iprot->readSetBegin(_etype462, _size459);
-            uint32_t _i463;
-            for (_i463 = 0; _i463 < _size459; ++_i463)
+            uint32_t _size521;
+            ::apache::thrift::protocol::TType _etype524;
+            xfer += iprot->readSetBegin(_etype524, _size521);
+            uint32_t _i525;
+            for (_i525 = 0; _i525 < _size521; ++_i525)
             {
-              std::string _elem464;
-              xfer += iprot->readBinary(_elem464);
-              this->authorizations.insert(_elem464);
+              std::string _elem526;
+              xfer += iprot->readBinary(_elem526);
+              this->authorizations.insert(_elem526);
             }
             xfer += iprot->readSetEnd();
           }
@@ -12314,6 +13520,7 @@
 
 uint32_t AccumuloProxy_changeUserAuthorizations_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_changeUserAuthorizations_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -12327,10 +13534,10 @@
   xfer += oprot->writeFieldBegin("authorizations", ::apache::thrift::protocol::T_SET, 3);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->authorizations.size()));
-    std::set<std::string> ::const_iterator _iter465;
-    for (_iter465 = this->authorizations.begin(); _iter465 != this->authorizations.end(); ++_iter465)
+    std::set<std::string> ::const_iterator _iter527;
+    for (_iter527 = this->authorizations.begin(); _iter527 != this->authorizations.end(); ++_iter527)
     {
-      xfer += oprot->writeBinary((*_iter465));
+      xfer += oprot->writeBinary((*_iter527));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -12341,8 +13548,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_changeUserAuthorizations_pargs::~AccumuloProxy_changeUserAuthorizations_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_changeUserAuthorizations_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_changeUserAuthorizations_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -12356,10 +13569,10 @@
   xfer += oprot->writeFieldBegin("authorizations", ::apache::thrift::protocol::T_SET, 3);
   {
     xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->authorizations)).size()));
-    std::set<std::string> ::const_iterator _iter466;
-    for (_iter466 = (*(this->authorizations)).begin(); _iter466 != (*(this->authorizations)).end(); ++_iter466)
+    std::set<std::string> ::const_iterator _iter528;
+    for (_iter528 = (*(this->authorizations)).begin(); _iter528 != (*(this->authorizations)).end(); ++_iter528)
     {
-      xfer += oprot->writeBinary((*_iter466));
+      xfer += oprot->writeBinary((*_iter528));
     }
     xfer += oprot->writeSetEnd();
   }
@@ -12370,8 +13583,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_changeUserAuthorizations_result::~AccumuloProxy_changeUserAuthorizations_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_changeUserAuthorizations_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12438,8 +13657,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_changeUserAuthorizations_presult::~AccumuloProxy_changeUserAuthorizations_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_changeUserAuthorizations_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12486,8 +13711,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_changeLocalUserPassword_args::~AccumuloProxy_changeLocalUserPassword_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_changeLocalUserPassword_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12544,6 +13775,7 @@
 
 uint32_t AccumuloProxy_changeLocalUserPassword_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_changeLocalUserPassword_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -12563,8 +13795,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_changeLocalUserPassword_pargs::~AccumuloProxy_changeLocalUserPassword_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_changeLocalUserPassword_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_changeLocalUserPassword_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -12584,8 +13822,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_changeLocalUserPassword_result::~AccumuloProxy_changeLocalUserPassword_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_changeLocalUserPassword_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12652,8 +13896,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_changeLocalUserPassword_presult::~AccumuloProxy_changeLocalUserPassword_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_changeLocalUserPassword_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12700,8 +13950,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createLocalUser_args::~AccumuloProxy_createLocalUser_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_createLocalUser_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12758,6 +14014,7 @@
 
 uint32_t AccumuloProxy_createLocalUser_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createLocalUser_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -12777,8 +14034,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createLocalUser_pargs::~AccumuloProxy_createLocalUser_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_createLocalUser_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createLocalUser_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -12798,8 +14061,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createLocalUser_result::~AccumuloProxy_createLocalUser_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_createLocalUser_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12866,8 +14135,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createLocalUser_presult::~AccumuloProxy_createLocalUser_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_createLocalUser_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12914,8 +14189,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_dropLocalUser_args::~AccumuloProxy_dropLocalUser_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_dropLocalUser_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -12964,6 +14245,7 @@
 
 uint32_t AccumuloProxy_dropLocalUser_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_dropLocalUser_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -12979,8 +14261,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_dropLocalUser_pargs::~AccumuloProxy_dropLocalUser_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_dropLocalUser_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_dropLocalUser_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -12996,8 +14284,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_dropLocalUser_result::~AccumuloProxy_dropLocalUser_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_dropLocalUser_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13064,8 +14358,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_dropLocalUser_presult::~AccumuloProxy_dropLocalUser_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_dropLocalUser_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13112,8 +14412,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getUserAuthorizations_args::~AccumuloProxy_getUserAuthorizations_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getUserAuthorizations_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13162,6 +14468,7 @@
 
 uint32_t AccumuloProxy_getUserAuthorizations_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getUserAuthorizations_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -13177,8 +14484,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getUserAuthorizations_pargs::~AccumuloProxy_getUserAuthorizations_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getUserAuthorizations_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getUserAuthorizations_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -13194,8 +14507,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getUserAuthorizations_result::~AccumuloProxy_getUserAuthorizations_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getUserAuthorizations_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13218,14 +14537,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->success.clear();
-            uint32_t _size467;
-            ::apache::thrift::protocol::TType _etype470;
-            xfer += iprot->readListBegin(_etype470, _size467);
-            this->success.resize(_size467);
-            uint32_t _i471;
-            for (_i471 = 0; _i471 < _size467; ++_i471)
+            uint32_t _size529;
+            ::apache::thrift::protocol::TType _etype532;
+            xfer += iprot->readListBegin(_etype532, _size529);
+            this->success.resize(_size529);
+            uint32_t _i533;
+            for (_i533 = 0; _i533 < _size529; ++_i533)
             {
-              xfer += iprot->readBinary(this->success[_i471]);
+              xfer += iprot->readBinary(this->success[_i533]);
             }
             xfer += iprot->readListEnd();
           }
@@ -13272,10 +14591,10 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
-      std::vector<std::string> ::const_iterator _iter472;
-      for (_iter472 = this->success.begin(); _iter472 != this->success.end(); ++_iter472)
+      std::vector<std::string> ::const_iterator _iter534;
+      for (_iter534 = this->success.begin(); _iter534 != this->success.end(); ++_iter534)
       {
-        xfer += oprot->writeBinary((*_iter472));
+        xfer += oprot->writeBinary((*_iter534));
       }
       xfer += oprot->writeListEnd();
     }
@@ -13294,8 +14613,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getUserAuthorizations_presult::~AccumuloProxy_getUserAuthorizations_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getUserAuthorizations_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13318,14 +14643,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             (*(this->success)).clear();
-            uint32_t _size473;
-            ::apache::thrift::protocol::TType _etype476;
-            xfer += iprot->readListBegin(_etype476, _size473);
-            (*(this->success)).resize(_size473);
-            uint32_t _i477;
-            for (_i477 = 0; _i477 < _size473; ++_i477)
+            uint32_t _size535;
+            ::apache::thrift::protocol::TType _etype538;
+            xfer += iprot->readListBegin(_etype538, _size535);
+            (*(this->success)).resize(_size535);
+            uint32_t _i539;
+            for (_i539 = 0; _i539 < _size535; ++_i539)
             {
-              xfer += iprot->readBinary((*(this->success))[_i477]);
+              xfer += iprot->readBinary((*(this->success))[_i539]);
             }
             xfer += iprot->readListEnd();
           }
@@ -13362,8 +14687,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_grantSystemPermission_args::~AccumuloProxy_grantSystemPermission_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_grantSystemPermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13400,9 +14731,9 @@
         break;
       case 3:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast478;
-          xfer += iprot->readI32(ecast478);
-          this->perm = (SystemPermission::type)ecast478;
+          int32_t ecast540;
+          xfer += iprot->readI32(ecast540);
+          this->perm = (SystemPermission::type)ecast540;
           this->__isset.perm = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -13422,6 +14753,7 @@
 
 uint32_t AccumuloProxy_grantSystemPermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_grantSystemPermission_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -13441,8 +14773,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_grantSystemPermission_pargs::~AccumuloProxy_grantSystemPermission_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_grantSystemPermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_grantSystemPermission_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -13462,8 +14800,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_grantSystemPermission_result::~AccumuloProxy_grantSystemPermission_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_grantSystemPermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13530,8 +14874,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_grantSystemPermission_presult::~AccumuloProxy_grantSystemPermission_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_grantSystemPermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13578,8 +14928,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_grantTablePermission_args::~AccumuloProxy_grantTablePermission_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_grantTablePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13624,9 +14980,9 @@
         break;
       case 4:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast479;
-          xfer += iprot->readI32(ecast479);
-          this->perm = (TablePermission::type)ecast479;
+          int32_t ecast541;
+          xfer += iprot->readI32(ecast541);
+          this->perm = (TablePermission::type)ecast541;
           this->__isset.perm = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -13646,6 +15002,7 @@
 
 uint32_t AccumuloProxy_grantTablePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_grantTablePermission_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -13669,8 +15026,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_grantTablePermission_pargs::~AccumuloProxy_grantTablePermission_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_grantTablePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_grantTablePermission_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -13694,8 +15057,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_grantTablePermission_result::~AccumuloProxy_grantTablePermission_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_grantTablePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13774,8 +15143,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_grantTablePermission_presult::~AccumuloProxy_grantTablePermission_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_grantTablePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13830,8 +15205,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasSystemPermission_args::~AccumuloProxy_hasSystemPermission_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasSystemPermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -13868,9 +15249,9 @@
         break;
       case 3:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast480;
-          xfer += iprot->readI32(ecast480);
-          this->perm = (SystemPermission::type)ecast480;
+          int32_t ecast542;
+          xfer += iprot->readI32(ecast542);
+          this->perm = (SystemPermission::type)ecast542;
           this->__isset.perm = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -13890,6 +15271,7 @@
 
 uint32_t AccumuloProxy_hasSystemPermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_hasSystemPermission_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -13909,8 +15291,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasSystemPermission_pargs::~AccumuloProxy_hasSystemPermission_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasSystemPermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_hasSystemPermission_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -13930,8 +15318,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasSystemPermission_result::~AccumuloProxy_hasSystemPermission_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasSystemPermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14010,8 +15404,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasSystemPermission_presult::~AccumuloProxy_hasSystemPermission_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasSystemPermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14066,8 +15466,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasTablePermission_args::~AccumuloProxy_hasTablePermission_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasTablePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14112,9 +15518,9 @@
         break;
       case 4:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast481;
-          xfer += iprot->readI32(ecast481);
-          this->perm = (TablePermission::type)ecast481;
+          int32_t ecast543;
+          xfer += iprot->readI32(ecast543);
+          this->perm = (TablePermission::type)ecast543;
           this->__isset.perm = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -14134,6 +15540,7 @@
 
 uint32_t AccumuloProxy_hasTablePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_hasTablePermission_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -14157,8 +15564,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasTablePermission_pargs::~AccumuloProxy_hasTablePermission_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasTablePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_hasTablePermission_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -14182,8 +15595,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasTablePermission_result::~AccumuloProxy_hasTablePermission_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasTablePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14274,8 +15693,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasTablePermission_presult::~AccumuloProxy_hasTablePermission_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasTablePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14338,8 +15763,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listLocalUsers_args::~AccumuloProxy_listLocalUsers_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_listLocalUsers_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14380,6 +15811,7 @@
 
 uint32_t AccumuloProxy_listLocalUsers_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_listLocalUsers_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -14391,8 +15823,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listLocalUsers_pargs::~AccumuloProxy_listLocalUsers_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_listLocalUsers_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_listLocalUsers_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -14404,8 +15842,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listLocalUsers_result::~AccumuloProxy_listLocalUsers_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_listLocalUsers_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14428,15 +15872,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->success.clear();
-            uint32_t _size482;
-            ::apache::thrift::protocol::TType _etype485;
-            xfer += iprot->readSetBegin(_etype485, _size482);
-            uint32_t _i486;
-            for (_i486 = 0; _i486 < _size482; ++_i486)
+            uint32_t _size544;
+            ::apache::thrift::protocol::TType _etype547;
+            xfer += iprot->readSetBegin(_etype547, _size544);
+            uint32_t _i548;
+            for (_i548 = 0; _i548 < _size544; ++_i548)
             {
-              std::string _elem487;
-              xfer += iprot->readString(_elem487);
-              this->success.insert(_elem487);
+              std::string _elem549;
+              xfer += iprot->readString(_elem549);
+              this->success.insert(_elem549);
             }
             xfer += iprot->readSetEnd();
           }
@@ -14491,10 +15935,10 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_SET, 0);
     {
       xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
-      std::set<std::string> ::const_iterator _iter488;
-      for (_iter488 = this->success.begin(); _iter488 != this->success.end(); ++_iter488)
+      std::set<std::string> ::const_iterator _iter550;
+      for (_iter550 = this->success.begin(); _iter550 != this->success.end(); ++_iter550)
       {
-        xfer += oprot->writeString((*_iter488));
+        xfer += oprot->writeString((*_iter550));
       }
       xfer += oprot->writeSetEnd();
     }
@@ -14517,8 +15961,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_listLocalUsers_presult::~AccumuloProxy_listLocalUsers_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_listLocalUsers_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14541,15 +15991,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             (*(this->success)).clear();
-            uint32_t _size489;
-            ::apache::thrift::protocol::TType _etype492;
-            xfer += iprot->readSetBegin(_etype492, _size489);
-            uint32_t _i493;
-            for (_i493 = 0; _i493 < _size489; ++_i493)
+            uint32_t _size551;
+            ::apache::thrift::protocol::TType _etype554;
+            xfer += iprot->readSetBegin(_etype554, _size551);
+            uint32_t _i555;
+            for (_i555 = 0; _i555 < _size551; ++_i555)
             {
-              std::string _elem494;
-              xfer += iprot->readString(_elem494);
-              (*(this->success)).insert(_elem494);
+              std::string _elem556;
+              xfer += iprot->readString(_elem556);
+              (*(this->success)).insert(_elem556);
             }
             xfer += iprot->readSetEnd();
           }
@@ -14594,8 +16044,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_revokeSystemPermission_args::~AccumuloProxy_revokeSystemPermission_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_revokeSystemPermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14632,9 +16088,9 @@
         break;
       case 3:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast495;
-          xfer += iprot->readI32(ecast495);
-          this->perm = (SystemPermission::type)ecast495;
+          int32_t ecast557;
+          xfer += iprot->readI32(ecast557);
+          this->perm = (SystemPermission::type)ecast557;
           this->__isset.perm = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -14654,6 +16110,7 @@
 
 uint32_t AccumuloProxy_revokeSystemPermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_revokeSystemPermission_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -14673,8 +16130,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_revokeSystemPermission_pargs::~AccumuloProxy_revokeSystemPermission_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_revokeSystemPermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_revokeSystemPermission_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -14694,8 +16157,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_revokeSystemPermission_result::~AccumuloProxy_revokeSystemPermission_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_revokeSystemPermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14762,8 +16231,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_revokeSystemPermission_presult::~AccumuloProxy_revokeSystemPermission_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_revokeSystemPermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14810,8 +16285,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_revokeTablePermission_args::~AccumuloProxy_revokeTablePermission_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_revokeTablePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -14856,9 +16337,9 @@
         break;
       case 4:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast496;
-          xfer += iprot->readI32(ecast496);
-          this->perm = (TablePermission::type)ecast496;
+          int32_t ecast558;
+          xfer += iprot->readI32(ecast558);
+          this->perm = (TablePermission::type)ecast558;
           this->__isset.perm = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -14878,6 +16359,7 @@
 
 uint32_t AccumuloProxy_revokeTablePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_revokeTablePermission_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -14901,8 +16383,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_revokeTablePermission_pargs::~AccumuloProxy_revokeTablePermission_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_revokeTablePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_revokeTablePermission_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -14926,8 +16414,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_revokeTablePermission_result::~AccumuloProxy_revokeTablePermission_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_revokeTablePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15006,8 +16500,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_revokeTablePermission_presult::~AccumuloProxy_revokeTablePermission_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_revokeTablePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15062,8 +16562,805 @@
   return xfer;
 }
 
+
+AccumuloProxy_grantNamespacePermission_args::~AccumuloProxy_grantNamespacePermission_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_grantNamespacePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->user);
+          this->__isset.user = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_I32) {
+          int32_t ecast559;
+          xfer += iprot->readI32(ecast559);
+          this->perm = (NamespacePermission::type)ecast559;
+          this->__isset.perm = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_grantNamespacePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_grantNamespacePermission_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->user);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
+  xfer += oprot->writeI32((int32_t)this->perm);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_grantNamespacePermission_pargs::~AccumuloProxy_grantNamespacePermission_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_grantNamespacePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_grantNamespacePermission_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->user)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
+  xfer += oprot->writeI32((int32_t)(*(this->perm)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_grantNamespacePermission_result::~AccumuloProxy_grantNamespacePermission_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_grantNamespacePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_grantNamespacePermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_grantNamespacePermission_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_grantNamespacePermission_presult::~AccumuloProxy_grantNamespacePermission_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_grantNamespacePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_hasNamespacePermission_args::~AccumuloProxy_hasNamespacePermission_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_hasNamespacePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->user);
+          this->__isset.user = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_I32) {
+          int32_t ecast560;
+          xfer += iprot->readI32(ecast560);
+          this->perm = (NamespacePermission::type)ecast560;
+          this->__isset.perm = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_hasNamespacePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_hasNamespacePermission_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->user);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
+  xfer += oprot->writeI32((int32_t)this->perm);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_hasNamespacePermission_pargs::~AccumuloProxy_hasNamespacePermission_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_hasNamespacePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_hasNamespacePermission_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->user)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
+  xfer += oprot->writeI32((int32_t)(*(this->perm)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_hasNamespacePermission_result::~AccumuloProxy_hasNamespacePermission_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_hasNamespacePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_BOOL) {
+          xfer += iprot->readBool(this->success);
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_hasNamespacePermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_hasNamespacePermission_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
+    xfer += oprot->writeBool(this->success);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_hasNamespacePermission_presult::~AccumuloProxy_hasNamespacePermission_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_hasNamespacePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_BOOL) {
+          xfer += iprot->readBool((*(this->success)));
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_revokeNamespacePermission_args::~AccumuloProxy_revokeNamespacePermission_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_revokeNamespacePermission_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->user);
+          this->__isset.user = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_I32) {
+          int32_t ecast561;
+          xfer += iprot->readI32(ecast561);
+          this->perm = (NamespacePermission::type)ecast561;
+          this->__isset.perm = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_revokeNamespacePermission_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_revokeNamespacePermission_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->user);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
+  xfer += oprot->writeI32((int32_t)this->perm);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_revokeNamespacePermission_pargs::~AccumuloProxy_revokeNamespacePermission_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_revokeNamespacePermission_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_revokeNamespacePermission_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("user", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->user)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("perm", ::apache::thrift::protocol::T_I32, 4);
+  xfer += oprot->writeI32((int32_t)(*(this->perm)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_revokeNamespacePermission_result::~AccumuloProxy_revokeNamespacePermission_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_revokeNamespacePermission_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_revokeNamespacePermission_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_revokeNamespacePermission_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_revokeNamespacePermission_presult::~AccumuloProxy_revokeNamespacePermission_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_revokeNamespacePermission_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_createBatchScanner_args::~AccumuloProxy_createBatchScanner_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_createBatchScanner_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15120,6 +17417,7 @@
 
 uint32_t AccumuloProxy_createBatchScanner_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createBatchScanner_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -15139,8 +17437,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createBatchScanner_pargs::~AccumuloProxy_createBatchScanner_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_createBatchScanner_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createBatchScanner_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -15160,8 +17464,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createBatchScanner_result::~AccumuloProxy_createBatchScanner_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_createBatchScanner_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15252,8 +17562,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createBatchScanner_presult::~AccumuloProxy_createBatchScanner_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_createBatchScanner_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15316,8 +17632,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createScanner_args::~AccumuloProxy_createScanner_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_createScanner_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15374,6 +17696,7 @@
 
 uint32_t AccumuloProxy_createScanner_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createScanner_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -15393,8 +17716,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createScanner_pargs::~AccumuloProxy_createScanner_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_createScanner_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createScanner_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -15414,8 +17743,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createScanner_result::~AccumuloProxy_createScanner_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_createScanner_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15506,8 +17841,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createScanner_presult::~AccumuloProxy_createScanner_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_createScanner_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15570,8 +17911,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasNext_args::~AccumuloProxy_hasNext_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasNext_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15612,6 +17959,7 @@
 
 uint32_t AccumuloProxy_hasNext_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_hasNext_args");
 
   xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
@@ -15623,8 +17971,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasNext_pargs::~AccumuloProxy_hasNext_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasNext_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_hasNext_pargs");
 
   xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
@@ -15636,8 +17990,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasNext_result::~AccumuloProxy_hasNext_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasNext_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15704,8 +18064,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_hasNext_presult::~AccumuloProxy_hasNext_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_hasNext_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15752,8 +18118,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_nextEntry_args::~AccumuloProxy_nextEntry_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_nextEntry_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15794,6 +18166,7 @@
 
 uint32_t AccumuloProxy_nextEntry_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_nextEntry_args");
 
   xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
@@ -15805,8 +18178,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_nextEntry_pargs::~AccumuloProxy_nextEntry_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_nextEntry_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_nextEntry_pargs");
 
   xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
@@ -15818,8 +18197,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_nextEntry_result::~AccumuloProxy_nextEntry_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_nextEntry_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15910,8 +18295,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_nextEntry_presult::~AccumuloProxy_nextEntry_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_nextEntry_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -15974,8 +18365,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_nextK_args::~AccumuloProxy_nextK_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_nextK_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16024,6 +18421,7 @@
 
 uint32_t AccumuloProxy_nextK_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_nextK_args");
 
   xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
@@ -16039,8 +18437,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_nextK_pargs::~AccumuloProxy_nextK_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_nextK_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_nextK_pargs");
 
   xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
@@ -16056,8 +18460,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_nextK_result::~AccumuloProxy_nextK_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_nextK_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16148,8 +18558,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_nextK_presult::~AccumuloProxy_nextK_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_nextK_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16212,8 +18628,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeScanner_args::~AccumuloProxy_closeScanner_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeScanner_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16254,6 +18676,7 @@
 
 uint32_t AccumuloProxy_closeScanner_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_closeScanner_args");
 
   xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
@@ -16265,8 +18688,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeScanner_pargs::~AccumuloProxy_closeScanner_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeScanner_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_closeScanner_pargs");
 
   xfer += oprot->writeFieldBegin("scanner", ::apache::thrift::protocol::T_STRING, 1);
@@ -16278,8 +18707,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeScanner_result::~AccumuloProxy_closeScanner_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeScanner_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16334,8 +18769,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeScanner_presult::~AccumuloProxy_closeScanner_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeScanner_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16374,8 +18815,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateAndFlush_args::~AccumuloProxy_updateAndFlush_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateAndFlush_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16414,26 +18861,26 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->cells.clear();
-            uint32_t _size497;
-            ::apache::thrift::protocol::TType _ktype498;
-            ::apache::thrift::protocol::TType _vtype499;
-            xfer += iprot->readMapBegin(_ktype498, _vtype499, _size497);
-            uint32_t _i501;
-            for (_i501 = 0; _i501 < _size497; ++_i501)
+            uint32_t _size562;
+            ::apache::thrift::protocol::TType _ktype563;
+            ::apache::thrift::protocol::TType _vtype564;
+            xfer += iprot->readMapBegin(_ktype563, _vtype564, _size562);
+            uint32_t _i566;
+            for (_i566 = 0; _i566 < _size562; ++_i566)
             {
-              std::string _key502;
-              xfer += iprot->readBinary(_key502);
-              std::vector<ColumnUpdate> & _val503 = this->cells[_key502];
+              std::string _key567;
+              xfer += iprot->readBinary(_key567);
+              std::vector<ColumnUpdate> & _val568 = this->cells[_key567];
               {
-                _val503.clear();
-                uint32_t _size504;
-                ::apache::thrift::protocol::TType _etype507;
-                xfer += iprot->readListBegin(_etype507, _size504);
-                _val503.resize(_size504);
-                uint32_t _i508;
-                for (_i508 = 0; _i508 < _size504; ++_i508)
+                _val568.clear();
+                uint32_t _size569;
+                ::apache::thrift::protocol::TType _etype572;
+                xfer += iprot->readListBegin(_etype572, _size569);
+                _val568.resize(_size569);
+                uint32_t _i573;
+                for (_i573 = 0; _i573 < _size569; ++_i573)
                 {
-                  xfer += _val503[_i508].read(iprot);
+                  xfer += _val568[_i573].read(iprot);
                 }
                 xfer += iprot->readListEnd();
               }
@@ -16459,6 +18906,7 @@
 
 uint32_t AccumuloProxy_updateAndFlush_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_updateAndFlush_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -16472,16 +18920,16 @@
   xfer += oprot->writeFieldBegin("cells", ::apache::thrift::protocol::T_MAP, 3);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast<uint32_t>(this->cells.size()));
-    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter509;
-    for (_iter509 = this->cells.begin(); _iter509 != this->cells.end(); ++_iter509)
+    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter574;
+    for (_iter574 = this->cells.begin(); _iter574 != this->cells.end(); ++_iter574)
     {
-      xfer += oprot->writeBinary(_iter509->first);
+      xfer += oprot->writeBinary(_iter574->first);
       {
-        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter509->second.size()));
-        std::vector<ColumnUpdate> ::const_iterator _iter510;
-        for (_iter510 = _iter509->second.begin(); _iter510 != _iter509->second.end(); ++_iter510)
+        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter574->second.size()));
+        std::vector<ColumnUpdate> ::const_iterator _iter575;
+        for (_iter575 = _iter574->second.begin(); _iter575 != _iter574->second.end(); ++_iter575)
         {
-          xfer += (*_iter510).write(oprot);
+          xfer += (*_iter575).write(oprot);
         }
         xfer += oprot->writeListEnd();
       }
@@ -16495,8 +18943,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateAndFlush_pargs::~AccumuloProxy_updateAndFlush_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateAndFlush_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_updateAndFlush_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -16510,16 +18964,16 @@
   xfer += oprot->writeFieldBegin("cells", ::apache::thrift::protocol::T_MAP, 3);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast<uint32_t>((*(this->cells)).size()));
-    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter511;
-    for (_iter511 = (*(this->cells)).begin(); _iter511 != (*(this->cells)).end(); ++_iter511)
+    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter576;
+    for (_iter576 = (*(this->cells)).begin(); _iter576 != (*(this->cells)).end(); ++_iter576)
     {
-      xfer += oprot->writeBinary(_iter511->first);
+      xfer += oprot->writeBinary(_iter576->first);
       {
-        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter511->second.size()));
-        std::vector<ColumnUpdate> ::const_iterator _iter512;
-        for (_iter512 = _iter511->second.begin(); _iter512 != _iter511->second.end(); ++_iter512)
+        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter576->second.size()));
+        std::vector<ColumnUpdate> ::const_iterator _iter577;
+        for (_iter577 = _iter576->second.begin(); _iter577 != _iter576->second.end(); ++_iter577)
         {
-          xfer += (*_iter512).write(oprot);
+          xfer += (*_iter577).write(oprot);
         }
         xfer += oprot->writeListEnd();
       }
@@ -16533,8 +18987,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateAndFlush_result::~AccumuloProxy_updateAndFlush_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateAndFlush_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16625,8 +19085,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateAndFlush_presult::~AccumuloProxy_updateAndFlush_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateAndFlush_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16689,8 +19155,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createWriter_args::~AccumuloProxy_createWriter_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_createWriter_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16747,6 +19219,7 @@
 
 uint32_t AccumuloProxy_createWriter_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createWriter_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -16766,8 +19239,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createWriter_pargs::~AccumuloProxy_createWriter_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_createWriter_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createWriter_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -16787,8 +19266,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createWriter_result::~AccumuloProxy_createWriter_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_createWriter_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16879,8 +19364,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createWriter_presult::~AccumuloProxy_createWriter_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_createWriter_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16943,8 +19434,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_update_args::~AccumuloProxy_update_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_update_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -16975,26 +19472,26 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->cells.clear();
-            uint32_t _size513;
-            ::apache::thrift::protocol::TType _ktype514;
-            ::apache::thrift::protocol::TType _vtype515;
-            xfer += iprot->readMapBegin(_ktype514, _vtype515, _size513);
-            uint32_t _i517;
-            for (_i517 = 0; _i517 < _size513; ++_i517)
+            uint32_t _size578;
+            ::apache::thrift::protocol::TType _ktype579;
+            ::apache::thrift::protocol::TType _vtype580;
+            xfer += iprot->readMapBegin(_ktype579, _vtype580, _size578);
+            uint32_t _i582;
+            for (_i582 = 0; _i582 < _size578; ++_i582)
             {
-              std::string _key518;
-              xfer += iprot->readBinary(_key518);
-              std::vector<ColumnUpdate> & _val519 = this->cells[_key518];
+              std::string _key583;
+              xfer += iprot->readBinary(_key583);
+              std::vector<ColumnUpdate> & _val584 = this->cells[_key583];
               {
-                _val519.clear();
-                uint32_t _size520;
-                ::apache::thrift::protocol::TType _etype523;
-                xfer += iprot->readListBegin(_etype523, _size520);
-                _val519.resize(_size520);
-                uint32_t _i524;
-                for (_i524 = 0; _i524 < _size520; ++_i524)
+                _val584.clear();
+                uint32_t _size585;
+                ::apache::thrift::protocol::TType _etype588;
+                xfer += iprot->readListBegin(_etype588, _size585);
+                _val584.resize(_size585);
+                uint32_t _i589;
+                for (_i589 = 0; _i589 < _size585; ++_i589)
                 {
-                  xfer += _val519[_i524].read(iprot);
+                  xfer += _val584[_i589].read(iprot);
                 }
                 xfer += iprot->readListEnd();
               }
@@ -17020,6 +19517,7 @@
 
 uint32_t AccumuloProxy_update_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_update_args");
 
   xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
@@ -17029,16 +19527,16 @@
   xfer += oprot->writeFieldBegin("cells", ::apache::thrift::protocol::T_MAP, 2);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast<uint32_t>(this->cells.size()));
-    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter525;
-    for (_iter525 = this->cells.begin(); _iter525 != this->cells.end(); ++_iter525)
+    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter590;
+    for (_iter590 = this->cells.begin(); _iter590 != this->cells.end(); ++_iter590)
     {
-      xfer += oprot->writeBinary(_iter525->first);
+      xfer += oprot->writeBinary(_iter590->first);
       {
-        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter525->second.size()));
-        std::vector<ColumnUpdate> ::const_iterator _iter526;
-        for (_iter526 = _iter525->second.begin(); _iter526 != _iter525->second.end(); ++_iter526)
+        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter590->second.size()));
+        std::vector<ColumnUpdate> ::const_iterator _iter591;
+        for (_iter591 = _iter590->second.begin(); _iter591 != _iter590->second.end(); ++_iter591)
         {
-          xfer += (*_iter526).write(oprot);
+          xfer += (*_iter591).write(oprot);
         }
         xfer += oprot->writeListEnd();
       }
@@ -17052,8 +19550,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_update_pargs::~AccumuloProxy_update_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_update_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_update_pargs");
 
   xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
@@ -17063,16 +19567,16 @@
   xfer += oprot->writeFieldBegin("cells", ::apache::thrift::protocol::T_MAP, 2);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast<uint32_t>((*(this->cells)).size()));
-    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter527;
-    for (_iter527 = (*(this->cells)).begin(); _iter527 != (*(this->cells)).end(); ++_iter527)
+    std::map<std::string, std::vector<ColumnUpdate> > ::const_iterator _iter592;
+    for (_iter592 = (*(this->cells)).begin(); _iter592 != (*(this->cells)).end(); ++_iter592)
     {
-      xfer += oprot->writeBinary(_iter527->first);
+      xfer += oprot->writeBinary(_iter592->first);
       {
-        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter527->second.size()));
-        std::vector<ColumnUpdate> ::const_iterator _iter528;
-        for (_iter528 = _iter527->second.begin(); _iter528 != _iter527->second.end(); ++_iter528)
+        xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(_iter592->second.size()));
+        std::vector<ColumnUpdate> ::const_iterator _iter593;
+        for (_iter593 = _iter592->second.begin(); _iter593 != _iter592->second.end(); ++_iter593)
         {
-          xfer += (*_iter528).write(oprot);
+          xfer += (*_iter593).write(oprot);
         }
         xfer += oprot->writeListEnd();
       }
@@ -17086,8 +19590,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_flush_args::~AccumuloProxy_flush_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_flush_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17128,6 +19638,7 @@
 
 uint32_t AccumuloProxy_flush_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_flush_args");
 
   xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
@@ -17139,8 +19650,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_flush_pargs::~AccumuloProxy_flush_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_flush_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_flush_pargs");
 
   xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
@@ -17152,8 +19669,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_flush_result::~AccumuloProxy_flush_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_flush_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17220,8 +19743,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_flush_presult::~AccumuloProxy_flush_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_flush_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17268,8 +19797,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeWriter_args::~AccumuloProxy_closeWriter_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeWriter_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17310,6 +19845,7 @@
 
 uint32_t AccumuloProxy_closeWriter_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_closeWriter_args");
 
   xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
@@ -17321,8 +19857,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeWriter_pargs::~AccumuloProxy_closeWriter_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeWriter_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_closeWriter_pargs");
 
   xfer += oprot->writeFieldBegin("writer", ::apache::thrift::protocol::T_STRING, 1);
@@ -17334,8 +19876,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeWriter_result::~AccumuloProxy_closeWriter_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeWriter_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17402,8 +19950,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeWriter_presult::~AccumuloProxy_closeWriter_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeWriter_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17450,8 +20004,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateRowConditionally_args::~AccumuloProxy_updateRowConditionally_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateRowConditionally_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17516,6 +20076,7 @@
 
 uint32_t AccumuloProxy_updateRowConditionally_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_updateRowConditionally_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -17539,8 +20100,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateRowConditionally_pargs::~AccumuloProxy_updateRowConditionally_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateRowConditionally_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_updateRowConditionally_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -17564,8 +20131,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateRowConditionally_result::~AccumuloProxy_updateRowConditionally_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateRowConditionally_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17586,9 +20159,9 @@
     {
       case 0:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast529;
-          xfer += iprot->readI32(ecast529);
-          this->success = (ConditionalStatus::type)ecast529;
+          int32_t ecast594;
+          xfer += iprot->readI32(ecast594);
+          this->success = (ConditionalStatus::type)ecast594;
           this->__isset.success = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -17658,8 +20231,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateRowConditionally_presult::~AccumuloProxy_updateRowConditionally_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateRowConditionally_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17680,9 +20259,9 @@
     {
       case 0:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast530;
-          xfer += iprot->readI32(ecast530);
-          (*(this->success)) = (ConditionalStatus::type)ecast530;
+          int32_t ecast595;
+          xfer += iprot->readI32(ecast595);
+          (*(this->success)) = (ConditionalStatus::type)ecast595;
           this->__isset.success = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -17724,8 +20303,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createConditionalWriter_args::~AccumuloProxy_createConditionalWriter_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_createConditionalWriter_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17782,6 +20367,7 @@
 
 uint32_t AccumuloProxy_createConditionalWriter_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createConditionalWriter_args");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -17801,8 +20387,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createConditionalWriter_pargs::~AccumuloProxy_createConditionalWriter_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_createConditionalWriter_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_createConditionalWriter_pargs");
 
   xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
@@ -17822,8 +20414,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createConditionalWriter_result::~AccumuloProxy_createConditionalWriter_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_createConditionalWriter_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17914,8 +20512,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_createConditionalWriter_presult::~AccumuloProxy_createConditionalWriter_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_createConditionalWriter_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -17978,8 +20582,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateRowsConditionally_args::~AccumuloProxy_updateRowsConditionally_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateRowsConditionally_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18010,17 +20620,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->updates.clear();
-            uint32_t _size531;
-            ::apache::thrift::protocol::TType _ktype532;
-            ::apache::thrift::protocol::TType _vtype533;
-            xfer += iprot->readMapBegin(_ktype532, _vtype533, _size531);
-            uint32_t _i535;
-            for (_i535 = 0; _i535 < _size531; ++_i535)
+            uint32_t _size596;
+            ::apache::thrift::protocol::TType _ktype597;
+            ::apache::thrift::protocol::TType _vtype598;
+            xfer += iprot->readMapBegin(_ktype597, _vtype598, _size596);
+            uint32_t _i600;
+            for (_i600 = 0; _i600 < _size596; ++_i600)
             {
-              std::string _key536;
-              xfer += iprot->readBinary(_key536);
-              ConditionalUpdates& _val537 = this->updates[_key536];
-              xfer += _val537.read(iprot);
+              std::string _key601;
+              xfer += iprot->readBinary(_key601);
+              ConditionalUpdates& _val602 = this->updates[_key601];
+              xfer += _val602.read(iprot);
             }
             xfer += iprot->readMapEnd();
           }
@@ -18043,6 +20653,7 @@
 
 uint32_t AccumuloProxy_updateRowsConditionally_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_updateRowsConditionally_args");
 
   xfer += oprot->writeFieldBegin("conditionalWriter", ::apache::thrift::protocol::T_STRING, 1);
@@ -18052,11 +20663,11 @@
   xfer += oprot->writeFieldBegin("updates", ::apache::thrift::protocol::T_MAP, 2);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->updates.size()));
-    std::map<std::string, ConditionalUpdates> ::const_iterator _iter538;
-    for (_iter538 = this->updates.begin(); _iter538 != this->updates.end(); ++_iter538)
+    std::map<std::string, ConditionalUpdates> ::const_iterator _iter603;
+    for (_iter603 = this->updates.begin(); _iter603 != this->updates.end(); ++_iter603)
     {
-      xfer += oprot->writeBinary(_iter538->first);
-      xfer += _iter538->second.write(oprot);
+      xfer += oprot->writeBinary(_iter603->first);
+      xfer += _iter603->second.write(oprot);
     }
     xfer += oprot->writeMapEnd();
   }
@@ -18067,8 +20678,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateRowsConditionally_pargs::~AccumuloProxy_updateRowsConditionally_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateRowsConditionally_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_updateRowsConditionally_pargs");
 
   xfer += oprot->writeFieldBegin("conditionalWriter", ::apache::thrift::protocol::T_STRING, 1);
@@ -18078,11 +20695,11 @@
   xfer += oprot->writeFieldBegin("updates", ::apache::thrift::protocol::T_MAP, 2);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>((*(this->updates)).size()));
-    std::map<std::string, ConditionalUpdates> ::const_iterator _iter539;
-    for (_iter539 = (*(this->updates)).begin(); _iter539 != (*(this->updates)).end(); ++_iter539)
+    std::map<std::string, ConditionalUpdates> ::const_iterator _iter604;
+    for (_iter604 = (*(this->updates)).begin(); _iter604 != (*(this->updates)).end(); ++_iter604)
     {
-      xfer += oprot->writeBinary(_iter539->first);
-      xfer += _iter539->second.write(oprot);
+      xfer += oprot->writeBinary(_iter604->first);
+      xfer += _iter604->second.write(oprot);
     }
     xfer += oprot->writeMapEnd();
   }
@@ -18093,8 +20710,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateRowsConditionally_result::~AccumuloProxy_updateRowsConditionally_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateRowsConditionally_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18117,19 +20740,19 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->success.clear();
-            uint32_t _size540;
-            ::apache::thrift::protocol::TType _ktype541;
-            ::apache::thrift::protocol::TType _vtype542;
-            xfer += iprot->readMapBegin(_ktype541, _vtype542, _size540);
-            uint32_t _i544;
-            for (_i544 = 0; _i544 < _size540; ++_i544)
+            uint32_t _size605;
+            ::apache::thrift::protocol::TType _ktype606;
+            ::apache::thrift::protocol::TType _vtype607;
+            xfer += iprot->readMapBegin(_ktype606, _vtype607, _size605);
+            uint32_t _i609;
+            for (_i609 = 0; _i609 < _size605; ++_i609)
             {
-              std::string _key545;
-              xfer += iprot->readBinary(_key545);
-              ConditionalStatus::type& _val546 = this->success[_key545];
-              int32_t ecast547;
-              xfer += iprot->readI32(ecast547);
-              _val546 = (ConditionalStatus::type)ecast547;
+              std::string _key610;
+              xfer += iprot->readBinary(_key610);
+              ConditionalStatus::type& _val611 = this->success[_key610];
+              int32_t ecast612;
+              xfer += iprot->readI32(ecast612);
+              _val611 = (ConditionalStatus::type)ecast612;
             }
             xfer += iprot->readMapEnd();
           }
@@ -18184,11 +20807,11 @@
     xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
     {
       xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->success.size()));
-      std::map<std::string, ConditionalStatus::type> ::const_iterator _iter548;
-      for (_iter548 = this->success.begin(); _iter548 != this->success.end(); ++_iter548)
+      std::map<std::string, ConditionalStatus::type> ::const_iterator _iter613;
+      for (_iter613 = this->success.begin(); _iter613 != this->success.end(); ++_iter613)
       {
-        xfer += oprot->writeBinary(_iter548->first);
-        xfer += oprot->writeI32((int32_t)_iter548->second);
+        xfer += oprot->writeBinary(_iter613->first);
+        xfer += oprot->writeI32((int32_t)_iter613->second);
       }
       xfer += oprot->writeMapEnd();
     }
@@ -18211,8 +20834,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_updateRowsConditionally_presult::~AccumuloProxy_updateRowsConditionally_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_updateRowsConditionally_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18235,19 +20864,19 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             (*(this->success)).clear();
-            uint32_t _size549;
-            ::apache::thrift::protocol::TType _ktype550;
-            ::apache::thrift::protocol::TType _vtype551;
-            xfer += iprot->readMapBegin(_ktype550, _vtype551, _size549);
-            uint32_t _i553;
-            for (_i553 = 0; _i553 < _size549; ++_i553)
+            uint32_t _size614;
+            ::apache::thrift::protocol::TType _ktype615;
+            ::apache::thrift::protocol::TType _vtype616;
+            xfer += iprot->readMapBegin(_ktype615, _vtype616, _size614);
+            uint32_t _i618;
+            for (_i618 = 0; _i618 < _size614; ++_i618)
             {
-              std::string _key554;
-              xfer += iprot->readBinary(_key554);
-              ConditionalStatus::type& _val555 = (*(this->success))[_key554];
-              int32_t ecast556;
-              xfer += iprot->readI32(ecast556);
-              _val555 = (ConditionalStatus::type)ecast556;
+              std::string _key619;
+              xfer += iprot->readBinary(_key619);
+              ConditionalStatus::type& _val620 = (*(this->success))[_key619];
+              int32_t ecast621;
+              xfer += iprot->readI32(ecast621);
+              _val620 = (ConditionalStatus::type)ecast621;
             }
             xfer += iprot->readMapEnd();
           }
@@ -18292,8 +20921,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeConditionalWriter_args::~AccumuloProxy_closeConditionalWriter_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeConditionalWriter_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18334,6 +20969,7 @@
 
 uint32_t AccumuloProxy_closeConditionalWriter_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_closeConditionalWriter_args");
 
   xfer += oprot->writeFieldBegin("conditionalWriter", ::apache::thrift::protocol::T_STRING, 1);
@@ -18345,8 +20981,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeConditionalWriter_pargs::~AccumuloProxy_closeConditionalWriter_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeConditionalWriter_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_closeConditionalWriter_pargs");
 
   xfer += oprot->writeFieldBegin("conditionalWriter", ::apache::thrift::protocol::T_STRING, 1);
@@ -18358,8 +21000,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeConditionalWriter_result::~AccumuloProxy_closeConditionalWriter_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeConditionalWriter_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18396,8 +21044,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_closeConditionalWriter_presult::~AccumuloProxy_closeConditionalWriter_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_closeConditionalWriter_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18423,8 +21077,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getRowRange_args::~AccumuloProxy_getRowRange_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getRowRange_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18465,6 +21125,7 @@
 
 uint32_t AccumuloProxy_getRowRange_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getRowRange_args");
 
   xfer += oprot->writeFieldBegin("row", ::apache::thrift::protocol::T_STRING, 1);
@@ -18476,8 +21137,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getRowRange_pargs::~AccumuloProxy_getRowRange_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getRowRange_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getRowRange_pargs");
 
   xfer += oprot->writeFieldBegin("row", ::apache::thrift::protocol::T_STRING, 1);
@@ -18489,8 +21156,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getRowRange_result::~AccumuloProxy_getRowRange_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getRowRange_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18545,8 +21218,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getRowRange_presult::~AccumuloProxy_getRowRange_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getRowRange_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18585,8 +21264,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getFollowing_args::~AccumuloProxy_getFollowing_args() throw() {
+}
+
+
 uint32_t AccumuloProxy_getFollowing_args::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18615,9 +21300,9 @@
         break;
       case 2:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast557;
-          xfer += iprot->readI32(ecast557);
-          this->part = (PartialKey::type)ecast557;
+          int32_t ecast622;
+          xfer += iprot->readI32(ecast622);
+          this->part = (PartialKey::type)ecast622;
           this->__isset.part = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -18637,6 +21322,7 @@
 
 uint32_t AccumuloProxy_getFollowing_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getFollowing_args");
 
   xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRUCT, 1);
@@ -18652,8 +21338,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getFollowing_pargs::~AccumuloProxy_getFollowing_pargs() throw() {
+}
+
+
 uint32_t AccumuloProxy_getFollowing_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloProxy_getFollowing_pargs");
 
   xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRUCT, 1);
@@ -18669,8 +21361,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getFollowing_result::~AccumuloProxy_getFollowing_result() throw() {
+}
+
+
 uint32_t AccumuloProxy_getFollowing_result::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18725,8 +21423,14 @@
   return xfer;
 }
 
+
+AccumuloProxy_getFollowing_presult::~AccumuloProxy_getFollowing_presult() throw() {
+}
+
+
 uint32_t AccumuloProxy_getFollowing_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -18765,6 +21469,5417 @@
   return xfer;
 }
 
+
+AccumuloProxy_systemNamespace_args::~AccumuloProxy_systemNamespace_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_systemNamespace_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    xfer += iprot->skip(ftype);
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_systemNamespace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_systemNamespace_args");
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_systemNamespace_pargs::~AccumuloProxy_systemNamespace_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_systemNamespace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_systemNamespace_pargs");
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_systemNamespace_result::~AccumuloProxy_systemNamespace_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_systemNamespace_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->success);
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_systemNamespace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_systemNamespace_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0);
+    xfer += oprot->writeString(this->success);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_systemNamespace_presult::~AccumuloProxy_systemNamespace_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_systemNamespace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString((*(this->success)));
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_defaultNamespace_args::~AccumuloProxy_defaultNamespace_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_defaultNamespace_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    xfer += iprot->skip(ftype);
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_defaultNamespace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_defaultNamespace_args");
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_defaultNamespace_pargs::~AccumuloProxy_defaultNamespace_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_defaultNamespace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_defaultNamespace_pargs");
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_defaultNamespace_result::~AccumuloProxy_defaultNamespace_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_defaultNamespace_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->success);
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_defaultNamespace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_defaultNamespace_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRING, 0);
+    xfer += oprot->writeString(this->success);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_defaultNamespace_presult::~AccumuloProxy_defaultNamespace_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_defaultNamespace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString((*(this->success)));
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaces_args::~AccumuloProxy_listNamespaces_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaces_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_listNamespaces_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaces_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaces_pargs::~AccumuloProxy_listNamespaces_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaces_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaces_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaces_result::~AccumuloProxy_listNamespaces_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaces_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_LIST) {
+          {
+            this->success.clear();
+            uint32_t _size623;
+            ::apache::thrift::protocol::TType _etype626;
+            xfer += iprot->readListBegin(_etype626, _size623);
+            this->success.resize(_size623);
+            uint32_t _i627;
+            for (_i627 = 0; _i627 < _size623; ++_i627)
+            {
+              xfer += iprot->readString(this->success[_i627]);
+            }
+            xfer += iprot->readListEnd();
+          }
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_listNamespaces_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaces_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_LIST, 0);
+    {
+      xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
+      std::vector<std::string> ::const_iterator _iter628;
+      for (_iter628 = this->success.begin(); _iter628 != this->success.end(); ++_iter628)
+      {
+        xfer += oprot->writeString((*_iter628));
+      }
+      xfer += oprot->writeListEnd();
+    }
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaces_presult::~AccumuloProxy_listNamespaces_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaces_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_LIST) {
+          {
+            (*(this->success)).clear();
+            uint32_t _size629;
+            ::apache::thrift::protocol::TType _etype632;
+            xfer += iprot->readListBegin(_etype632, _size629);
+            (*(this->success)).resize(_size629);
+            uint32_t _i633;
+            for (_i633 = 0; _i633 < _size629; ++_i633)
+            {
+              xfer += iprot->readString((*(this->success))[_i633]);
+            }
+            xfer += iprot->readListEnd();
+          }
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_namespaceExists_args::~AccumuloProxy_namespaceExists_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_namespaceExists_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_namespaceExists_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceExists_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_namespaceExists_pargs::~AccumuloProxy_namespaceExists_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_namespaceExists_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceExists_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_namespaceExists_result::~AccumuloProxy_namespaceExists_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_namespaceExists_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_BOOL) {
+          xfer += iprot->readBool(this->success);
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_namespaceExists_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceExists_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
+    xfer += oprot->writeBool(this->success);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_namespaceExists_presult::~AccumuloProxy_namespaceExists_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_namespaceExists_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_BOOL) {
+          xfer += iprot->readBool((*(this->success)));
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_createNamespace_args::~AccumuloProxy_createNamespace_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_createNamespace_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_createNamespace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_createNamespace_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_createNamespace_pargs::~AccumuloProxy_createNamespace_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_createNamespace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_createNamespace_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_createNamespace_result::~AccumuloProxy_createNamespace_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_createNamespace_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_createNamespace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_createNamespace_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_createNamespace_presult::~AccumuloProxy_createNamespace_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_createNamespace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_deleteNamespace_args::~AccumuloProxy_deleteNamespace_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_deleteNamespace_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_deleteNamespace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_deleteNamespace_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_deleteNamespace_pargs::~AccumuloProxy_deleteNamespace_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_deleteNamespace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_deleteNamespace_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_deleteNamespace_result::~AccumuloProxy_deleteNamespace_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_deleteNamespace_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch4.read(iprot);
+          this->__isset.ouch4 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_deleteNamespace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_deleteNamespace_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch4) {
+    xfer += oprot->writeFieldBegin("ouch4", ::apache::thrift::protocol::T_STRUCT, 4);
+    xfer += this->ouch4.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_deleteNamespace_presult::~AccumuloProxy_deleteNamespace_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_deleteNamespace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch4.read(iprot);
+          this->__isset.ouch4 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_renameNamespace_args::~AccumuloProxy_renameNamespace_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_renameNamespace_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->oldNamespaceName);
+          this->__isset.oldNamespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->newNamespaceName);
+          this->__isset.newNamespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_renameNamespace_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_renameNamespace_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("oldNamespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->oldNamespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("newNamespaceName", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString(this->newNamespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_renameNamespace_pargs::~AccumuloProxy_renameNamespace_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_renameNamespace_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_renameNamespace_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("oldNamespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->oldNamespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("newNamespaceName", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString((*(this->newNamespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_renameNamespace_result::~AccumuloProxy_renameNamespace_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_renameNamespace_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch4.read(iprot);
+          this->__isset.ouch4 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_renameNamespace_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_renameNamespace_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch4) {
+    xfer += oprot->writeFieldBegin("ouch4", ::apache::thrift::protocol::T_STRUCT, 4);
+    xfer += this->ouch4.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_renameNamespace_presult::~AccumuloProxy_renameNamespace_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_renameNamespace_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch4.read(iprot);
+          this->__isset.ouch4 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_setNamespaceProperty_args::~AccumuloProxy_setNamespaceProperty_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_setNamespaceProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->property);
+          this->__isset.property = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->value);
+          this->__isset.value = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_setNamespaceProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_setNamespaceProperty_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString(this->property);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 4);
+  xfer += oprot->writeString(this->value);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_setNamespaceProperty_pargs::~AccumuloProxy_setNamespaceProperty_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_setNamespaceProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_setNamespaceProperty_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString((*(this->property)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 4);
+  xfer += oprot->writeString((*(this->value)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_setNamespaceProperty_result::~AccumuloProxy_setNamespaceProperty_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_setNamespaceProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_setNamespaceProperty_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_setNamespaceProperty_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_setNamespaceProperty_presult::~AccumuloProxy_setNamespaceProperty_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_setNamespaceProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceProperty_args::~AccumuloProxy_removeNamespaceProperty_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceProperty_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->property);
+          this->__isset.property = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_removeNamespaceProperty_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceProperty_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString(this->property);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceProperty_pargs::~AccumuloProxy_removeNamespaceProperty_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceProperty_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceProperty_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("property", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString((*(this->property)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceProperty_result::~AccumuloProxy_removeNamespaceProperty_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceProperty_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_removeNamespaceProperty_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceProperty_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceProperty_presult::~AccumuloProxy_removeNamespaceProperty_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceProperty_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_getNamespaceProperties_args::~AccumuloProxy_getNamespaceProperties_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_getNamespaceProperties_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_getNamespaceProperties_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceProperties_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_getNamespaceProperties_pargs::~AccumuloProxy_getNamespaceProperties_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_getNamespaceProperties_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceProperties_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_getNamespaceProperties_result::~AccumuloProxy_getNamespaceProperties_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_getNamespaceProperties_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_MAP) {
+          {
+            this->success.clear();
+            uint32_t _size634;
+            ::apache::thrift::protocol::TType _ktype635;
+            ::apache::thrift::protocol::TType _vtype636;
+            xfer += iprot->readMapBegin(_ktype635, _vtype636, _size634);
+            uint32_t _i638;
+            for (_i638 = 0; _i638 < _size634; ++_i638)
+            {
+              std::string _key639;
+              xfer += iprot->readString(_key639);
+              std::string& _val640 = this->success[_key639];
+              xfer += iprot->readString(_val640);
+            }
+            xfer += iprot->readMapEnd();
+          }
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_getNamespaceProperties_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceProperties_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
+    {
+      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
+      std::map<std::string, std::string> ::const_iterator _iter641;
+      for (_iter641 = this->success.begin(); _iter641 != this->success.end(); ++_iter641)
+      {
+        xfer += oprot->writeString(_iter641->first);
+        xfer += oprot->writeString(_iter641->second);
+      }
+      xfer += oprot->writeMapEnd();
+    }
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_getNamespaceProperties_presult::~AccumuloProxy_getNamespaceProperties_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_getNamespaceProperties_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_MAP) {
+          {
+            (*(this->success)).clear();
+            uint32_t _size642;
+            ::apache::thrift::protocol::TType _ktype643;
+            ::apache::thrift::protocol::TType _vtype644;
+            xfer += iprot->readMapBegin(_ktype643, _vtype644, _size642);
+            uint32_t _i646;
+            for (_i646 = 0; _i646 < _size642; ++_i646)
+            {
+              std::string _key647;
+              xfer += iprot->readString(_key647);
+              std::string& _val648 = (*(this->success))[_key647];
+              xfer += iprot->readString(_val648);
+            }
+            xfer += iprot->readMapEnd();
+          }
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_namespaceIdMap_args::~AccumuloProxy_namespaceIdMap_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_namespaceIdMap_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_namespaceIdMap_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceIdMap_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_namespaceIdMap_pargs::~AccumuloProxy_namespaceIdMap_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_namespaceIdMap_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceIdMap_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_namespaceIdMap_result::~AccumuloProxy_namespaceIdMap_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_namespaceIdMap_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_MAP) {
+          {
+            this->success.clear();
+            uint32_t _size649;
+            ::apache::thrift::protocol::TType _ktype650;
+            ::apache::thrift::protocol::TType _vtype651;
+            xfer += iprot->readMapBegin(_ktype650, _vtype651, _size649);
+            uint32_t _i653;
+            for (_i653 = 0; _i653 < _size649; ++_i653)
+            {
+              std::string _key654;
+              xfer += iprot->readString(_key654);
+              std::string& _val655 = this->success[_key654];
+              xfer += iprot->readString(_val655);
+            }
+            xfer += iprot->readMapEnd();
+          }
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_namespaceIdMap_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_namespaceIdMap_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
+    {
+      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->success.size()));
+      std::map<std::string, std::string> ::const_iterator _iter656;
+      for (_iter656 = this->success.begin(); _iter656 != this->success.end(); ++_iter656)
+      {
+        xfer += oprot->writeString(_iter656->first);
+        xfer += oprot->writeString(_iter656->second);
+      }
+      xfer += oprot->writeMapEnd();
+    }
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_namespaceIdMap_presult::~AccumuloProxy_namespaceIdMap_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_namespaceIdMap_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_MAP) {
+          {
+            (*(this->success)).clear();
+            uint32_t _size657;
+            ::apache::thrift::protocol::TType _ktype658;
+            ::apache::thrift::protocol::TType _vtype659;
+            xfer += iprot->readMapBegin(_ktype658, _vtype659, _size657);
+            uint32_t _i661;
+            for (_i661 = 0; _i661 < _size657; ++_i661)
+            {
+              std::string _key662;
+              xfer += iprot->readString(_key662);
+              std::string& _val663 = (*(this->success))[_key662];
+              xfer += iprot->readString(_val663);
+            }
+            xfer += iprot->readMapEnd();
+          }
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_attachNamespaceIterator_args::~AccumuloProxy_attachNamespaceIterator_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_attachNamespaceIterator_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->setting.read(iprot);
+          this->__isset.setting = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_SET) {
+          {
+            this->scopes.clear();
+            uint32_t _size664;
+            ::apache::thrift::protocol::TType _etype667;
+            xfer += iprot->readSetBegin(_etype667, _size664);
+            uint32_t _i668;
+            for (_i668 = 0; _i668 < _size664; ++_i668)
+            {
+              IteratorScope::type _elem669;
+              int32_t ecast670;
+              xfer += iprot->readI32(ecast670);
+              _elem669 = (IteratorScope::type)ecast670;
+              this->scopes.insert(_elem669);
+            }
+            xfer += iprot->readSetEnd();
+          }
+          this->__isset.scopes = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_attachNamespaceIterator_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_attachNamespaceIterator_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
+  xfer += this->setting.write(oprot);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
+  {
+    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
+    std::set<IteratorScope::type> ::const_iterator _iter671;
+    for (_iter671 = this->scopes.begin(); _iter671 != this->scopes.end(); ++_iter671)
+    {
+      xfer += oprot->writeI32((int32_t)(*_iter671));
+    }
+    xfer += oprot->writeSetEnd();
+  }
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_attachNamespaceIterator_pargs::~AccumuloProxy_attachNamespaceIterator_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_attachNamespaceIterator_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_attachNamespaceIterator_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
+  xfer += (*(this->setting)).write(oprot);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
+  {
+    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
+    std::set<IteratorScope::type> ::const_iterator _iter672;
+    for (_iter672 = (*(this->scopes)).begin(); _iter672 != (*(this->scopes)).end(); ++_iter672)
+    {
+      xfer += oprot->writeI32((int32_t)(*_iter672));
+    }
+    xfer += oprot->writeSetEnd();
+  }
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_attachNamespaceIterator_result::~AccumuloProxy_attachNamespaceIterator_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_attachNamespaceIterator_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_attachNamespaceIterator_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_attachNamespaceIterator_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_attachNamespaceIterator_presult::~AccumuloProxy_attachNamespaceIterator_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_attachNamespaceIterator_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceIterator_args::~AccumuloProxy_removeNamespaceIterator_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceIterator_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->name);
+          this->__isset.name = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_SET) {
+          {
+            this->scopes.clear();
+            uint32_t _size673;
+            ::apache::thrift::protocol::TType _etype676;
+            xfer += iprot->readSetBegin(_etype676, _size673);
+            uint32_t _i677;
+            for (_i677 = 0; _i677 < _size673; ++_i677)
+            {
+              IteratorScope::type _elem678;
+              int32_t ecast679;
+              xfer += iprot->readI32(ecast679);
+              _elem678 = (IteratorScope::type)ecast679;
+              this->scopes.insert(_elem678);
+            }
+            xfer += iprot->readSetEnd();
+          }
+          this->__isset.scopes = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_removeNamespaceIterator_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceIterator_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString(this->name);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
+  {
+    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
+    std::set<IteratorScope::type> ::const_iterator _iter680;
+    for (_iter680 = this->scopes.begin(); _iter680 != this->scopes.end(); ++_iter680)
+    {
+      xfer += oprot->writeI32((int32_t)(*_iter680));
+    }
+    xfer += oprot->writeSetEnd();
+  }
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceIterator_pargs::~AccumuloProxy_removeNamespaceIterator_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceIterator_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceIterator_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString((*(this->name)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
+  {
+    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
+    std::set<IteratorScope::type> ::const_iterator _iter681;
+    for (_iter681 = (*(this->scopes)).begin(); _iter681 != (*(this->scopes)).end(); ++_iter681)
+    {
+      xfer += oprot->writeI32((int32_t)(*_iter681));
+    }
+    xfer += oprot->writeSetEnd();
+  }
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceIterator_result::~AccumuloProxy_removeNamespaceIterator_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceIterator_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_removeNamespaceIterator_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceIterator_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceIterator_presult::~AccumuloProxy_removeNamespaceIterator_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceIterator_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_getNamespaceIteratorSetting_args::~AccumuloProxy_getNamespaceIteratorSetting_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_getNamespaceIteratorSetting_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->name);
+          this->__isset.name = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_I32) {
+          int32_t ecast682;
+          xfer += iprot->readI32(ecast682);
+          this->scope = (IteratorScope::type)ecast682;
+          this->__isset.scope = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_getNamespaceIteratorSetting_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceIteratorSetting_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString(this->name);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("scope", ::apache::thrift::protocol::T_I32, 4);
+  xfer += oprot->writeI32((int32_t)this->scope);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_getNamespaceIteratorSetting_pargs::~AccumuloProxy_getNamespaceIteratorSetting_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_getNamespaceIteratorSetting_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceIteratorSetting_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString((*(this->name)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("scope", ::apache::thrift::protocol::T_I32, 4);
+  xfer += oprot->writeI32((int32_t)(*(this->scope)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_getNamespaceIteratorSetting_result::~AccumuloProxy_getNamespaceIteratorSetting_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_getNamespaceIteratorSetting_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->success.read(iprot);
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_getNamespaceIteratorSetting_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_getNamespaceIteratorSetting_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
+    xfer += this->success.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_getNamespaceIteratorSetting_presult::~AccumuloProxy_getNamespaceIteratorSetting_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_getNamespaceIteratorSetting_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += (*(this->success)).read(iprot);
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaceIterators_args::~AccumuloProxy_listNamespaceIterators_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaceIterators_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_listNamespaceIterators_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceIterators_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaceIterators_pargs::~AccumuloProxy_listNamespaceIterators_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaceIterators_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceIterators_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaceIterators_result::~AccumuloProxy_listNamespaceIterators_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaceIterators_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_MAP) {
+          {
+            this->success.clear();
+            uint32_t _size683;
+            ::apache::thrift::protocol::TType _ktype684;
+            ::apache::thrift::protocol::TType _vtype685;
+            xfer += iprot->readMapBegin(_ktype684, _vtype685, _size683);
+            uint32_t _i687;
+            for (_i687 = 0; _i687 < _size683; ++_i687)
+            {
+              std::string _key688;
+              xfer += iprot->readString(_key688);
+              std::set<IteratorScope::type> & _val689 = this->success[_key688];
+              {
+                _val689.clear();
+                uint32_t _size690;
+                ::apache::thrift::protocol::TType _etype693;
+                xfer += iprot->readSetBegin(_etype693, _size690);
+                uint32_t _i694;
+                for (_i694 = 0; _i694 < _size690; ++_i694)
+                {
+                  IteratorScope::type _elem695;
+                  int32_t ecast696;
+                  xfer += iprot->readI32(ecast696);
+                  _elem695 = (IteratorScope::type)ecast696;
+                  _val689.insert(_elem695);
+                }
+                xfer += iprot->readSetEnd();
+              }
+            }
+            xfer += iprot->readMapEnd();
+          }
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_listNamespaceIterators_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceIterators_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
+    {
+      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_SET, static_cast<uint32_t>(this->success.size()));
+      std::map<std::string, std::set<IteratorScope::type> > ::const_iterator _iter697;
+      for (_iter697 = this->success.begin(); _iter697 != this->success.end(); ++_iter697)
+      {
+        xfer += oprot->writeString(_iter697->first);
+        {
+          xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(_iter697->second.size()));
+          std::set<IteratorScope::type> ::const_iterator _iter698;
+          for (_iter698 = _iter697->second.begin(); _iter698 != _iter697->second.end(); ++_iter698)
+          {
+            xfer += oprot->writeI32((int32_t)(*_iter698));
+          }
+          xfer += oprot->writeSetEnd();
+        }
+      }
+      xfer += oprot->writeMapEnd();
+    }
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaceIterators_presult::~AccumuloProxy_listNamespaceIterators_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaceIterators_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_MAP) {
+          {
+            (*(this->success)).clear();
+            uint32_t _size699;
+            ::apache::thrift::protocol::TType _ktype700;
+            ::apache::thrift::protocol::TType _vtype701;
+            xfer += iprot->readMapBegin(_ktype700, _vtype701, _size699);
+            uint32_t _i703;
+            for (_i703 = 0; _i703 < _size699; ++_i703)
+            {
+              std::string _key704;
+              xfer += iprot->readString(_key704);
+              std::set<IteratorScope::type> & _val705 = (*(this->success))[_key704];
+              {
+                _val705.clear();
+                uint32_t _size706;
+                ::apache::thrift::protocol::TType _etype709;
+                xfer += iprot->readSetBegin(_etype709, _size706);
+                uint32_t _i710;
+                for (_i710 = 0; _i710 < _size706; ++_i710)
+                {
+                  IteratorScope::type _elem711;
+                  int32_t ecast712;
+                  xfer += iprot->readI32(ecast712);
+                  _elem711 = (IteratorScope::type)ecast712;
+                  _val705.insert(_elem711);
+                }
+                xfer += iprot->readSetEnd();
+              }
+            }
+            xfer += iprot->readMapEnd();
+          }
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_checkNamespaceIteratorConflicts_args::~AccumuloProxy_checkNamespaceIteratorConflicts_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->setting.read(iprot);
+          this->__isset.setting = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_SET) {
+          {
+            this->scopes.clear();
+            uint32_t _size713;
+            ::apache::thrift::protocol::TType _etype716;
+            xfer += iprot->readSetBegin(_etype716, _size713);
+            uint32_t _i717;
+            for (_i717 = 0; _i717 < _size713; ++_i717)
+            {
+              IteratorScope::type _elem718;
+              int32_t ecast719;
+              xfer += iprot->readI32(ecast719);
+              _elem718 = (IteratorScope::type)ecast719;
+              this->scopes.insert(_elem718);
+            }
+            xfer += iprot->readSetEnd();
+          }
+          this->__isset.scopes = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_checkNamespaceIteratorConflicts_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
+  xfer += this->setting.write(oprot);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
+  {
+    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->scopes.size()));
+    std::set<IteratorScope::type> ::const_iterator _iter720;
+    for (_iter720 = this->scopes.begin(); _iter720 != this->scopes.end(); ++_iter720)
+    {
+      xfer += oprot->writeI32((int32_t)(*_iter720));
+    }
+    xfer += oprot->writeSetEnd();
+  }
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_checkNamespaceIteratorConflicts_pargs::~AccumuloProxy_checkNamespaceIteratorConflicts_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_checkNamespaceIteratorConflicts_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("setting", ::apache::thrift::protocol::T_STRUCT, 3);
+  xfer += (*(this->setting)).write(oprot);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("scopes", ::apache::thrift::protocol::T_SET, 4);
+  {
+    xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_I32, static_cast<uint32_t>((*(this->scopes)).size()));
+    std::set<IteratorScope::type> ::const_iterator _iter721;
+    for (_iter721 = (*(this->scopes)).begin(); _iter721 != (*(this->scopes)).end(); ++_iter721)
+    {
+      xfer += oprot->writeI32((int32_t)(*_iter721));
+    }
+    xfer += oprot->writeSetEnd();
+  }
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_checkNamespaceIteratorConflicts_result::~AccumuloProxy_checkNamespaceIteratorConflicts_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_checkNamespaceIteratorConflicts_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_checkNamespaceIteratorConflicts_presult::~AccumuloProxy_checkNamespaceIteratorConflicts_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_checkNamespaceIteratorConflicts_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_addNamespaceConstraint_args::~AccumuloProxy_addNamespaceConstraint_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_addNamespaceConstraint_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->constraintClassName);
+          this->__isset.constraintClassName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_addNamespaceConstraint_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_addNamespaceConstraint_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("constraintClassName", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString(this->constraintClassName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_addNamespaceConstraint_pargs::~AccumuloProxy_addNamespaceConstraint_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_addNamespaceConstraint_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_addNamespaceConstraint_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("constraintClassName", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString((*(this->constraintClassName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_addNamespaceConstraint_result::~AccumuloProxy_addNamespaceConstraint_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_addNamespaceConstraint_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_I32) {
+          xfer += iprot->readI32(this->success);
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_addNamespaceConstraint_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_addNamespaceConstraint_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_I32, 0);
+    xfer += oprot->writeI32(this->success);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_addNamespaceConstraint_presult::~AccumuloProxy_addNamespaceConstraint_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_addNamespaceConstraint_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_I32) {
+          xfer += iprot->readI32((*(this->success)));
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceConstraint_args::~AccumuloProxy_removeNamespaceConstraint_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceConstraint_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_I32) {
+          xfer += iprot->readI32(this->id);
+          this->__isset.id = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_removeNamespaceConstraint_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceConstraint_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("id", ::apache::thrift::protocol::T_I32, 3);
+  xfer += oprot->writeI32(this->id);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceConstraint_pargs::~AccumuloProxy_removeNamespaceConstraint_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceConstraint_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceConstraint_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("id", ::apache::thrift::protocol::T_I32, 3);
+  xfer += oprot->writeI32((*(this->id)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceConstraint_result::~AccumuloProxy_removeNamespaceConstraint_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceConstraint_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_removeNamespaceConstraint_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_removeNamespaceConstraint_result");
+
+  if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_removeNamespaceConstraint_presult::~AccumuloProxy_removeNamespaceConstraint_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_removeNamespaceConstraint_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaceConstraints_args::~AccumuloProxy_listNamespaceConstraints_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaceConstraints_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_listNamespaceConstraints_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceConstraints_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaceConstraints_pargs::~AccumuloProxy_listNamespaceConstraints_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaceConstraints_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceConstraints_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaceConstraints_result::~AccumuloProxy_listNamespaceConstraints_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaceConstraints_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_MAP) {
+          {
+            this->success.clear();
+            uint32_t _size722;
+            ::apache::thrift::protocol::TType _ktype723;
+            ::apache::thrift::protocol::TType _vtype724;
+            xfer += iprot->readMapBegin(_ktype723, _vtype724, _size722);
+            uint32_t _i726;
+            for (_i726 = 0; _i726 < _size722; ++_i726)
+            {
+              std::string _key727;
+              xfer += iprot->readString(_key727);
+              int32_t& _val728 = this->success[_key727];
+              xfer += iprot->readI32(_val728);
+            }
+            xfer += iprot->readMapEnd();
+          }
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_listNamespaceConstraints_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_listNamespaceConstraints_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
+    {
+      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_I32, static_cast<uint32_t>(this->success.size()));
+      std::map<std::string, int32_t> ::const_iterator _iter729;
+      for (_iter729 = this->success.begin(); _iter729 != this->success.end(); ++_iter729)
+      {
+        xfer += oprot->writeString(_iter729->first);
+        xfer += oprot->writeI32(_iter729->second);
+      }
+      xfer += oprot->writeMapEnd();
+    }
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_listNamespaceConstraints_presult::~AccumuloProxy_listNamespaceConstraints_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_listNamespaceConstraints_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_MAP) {
+          {
+            (*(this->success)).clear();
+            uint32_t _size730;
+            ::apache::thrift::protocol::TType _ktype731;
+            ::apache::thrift::protocol::TType _vtype732;
+            xfer += iprot->readMapBegin(_ktype731, _vtype732, _size730);
+            uint32_t _i734;
+            for (_i734 = 0; _i734 < _size730; ++_i734)
+            {
+              std::string _key735;
+              xfer += iprot->readString(_key735);
+              int32_t& _val736 = (*(this->success))[_key735];
+              xfer += iprot->readI32(_val736);
+            }
+            xfer += iprot->readMapEnd();
+          }
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+
+AccumuloProxy_testNamespaceClassLoad_args::~AccumuloProxy_testNamespaceClassLoad_args() throw() {
+}
+
+
+uint32_t AccumuloProxy_testNamespaceClassLoad_args::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readBinary(this->login);
+          this->__isset.login = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->namespaceName);
+          this->__isset.namespaceName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->className);
+          this->__isset.className = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 4:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->asTypeName);
+          this->__isset.asTypeName = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_testNamespaceClassLoad_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_testNamespaceClassLoad_args");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary(this->login);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString(this->namespaceName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("className", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString(this->className);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("asTypeName", ::apache::thrift::protocol::T_STRING, 4);
+  xfer += oprot->writeString(this->asTypeName);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_testNamespaceClassLoad_pargs::~AccumuloProxy_testNamespaceClassLoad_pargs() throw() {
+}
+
+
+uint32_t AccumuloProxy_testNamespaceClassLoad_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("AccumuloProxy_testNamespaceClassLoad_pargs");
+
+  xfer += oprot->writeFieldBegin("login", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeBinary((*(this->login)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("namespaceName", ::apache::thrift::protocol::T_STRING, 2);
+  xfer += oprot->writeString((*(this->namespaceName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("className", ::apache::thrift::protocol::T_STRING, 3);
+  xfer += oprot->writeString((*(this->className)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldBegin("asTypeName", ::apache::thrift::protocol::T_STRING, 4);
+  xfer += oprot->writeString((*(this->asTypeName)));
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_testNamespaceClassLoad_result::~AccumuloProxy_testNamespaceClassLoad_result() throw() {
+}
+
+
+uint32_t AccumuloProxy_testNamespaceClassLoad_result::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_BOOL) {
+          xfer += iprot->readBool(this->success);
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t AccumuloProxy_testNamespaceClassLoad_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
+
+  uint32_t xfer = 0;
+
+  xfer += oprot->writeStructBegin("AccumuloProxy_testNamespaceClassLoad_result");
+
+  if (this->__isset.success) {
+    xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_BOOL, 0);
+    xfer += oprot->writeBool(this->success);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch1) {
+    xfer += oprot->writeFieldBegin("ouch1", ::apache::thrift::protocol::T_STRUCT, 1);
+    xfer += this->ouch1.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch2) {
+    xfer += oprot->writeFieldBegin("ouch2", ::apache::thrift::protocol::T_STRUCT, 2);
+    xfer += this->ouch2.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  } else if (this->__isset.ouch3) {
+    xfer += oprot->writeFieldBegin("ouch3", ::apache::thrift::protocol::T_STRUCT, 3);
+    xfer += this->ouch3.write(oprot);
+    xfer += oprot->writeFieldEnd();
+  }
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+
+AccumuloProxy_testNamespaceClassLoad_presult::~AccumuloProxy_testNamespaceClassLoad_presult() throw() {
+}
+
+
+uint32_t AccumuloProxy_testNamespaceClassLoad_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 0:
+        if (ftype == ::apache::thrift::protocol::T_BOOL) {
+          xfer += iprot->readBool((*(this->success)));
+          this->__isset.success = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch1.read(iprot);
+          this->__isset.ouch1 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch2.read(iprot);
+          this->__isset.ouch2 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      case 3:
+        if (ftype == ::apache::thrift::protocol::T_STRUCT) {
+          xfer += this->ouch3.read(iprot);
+          this->__isset.ouch3 = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
 void AccumuloProxyClient::login(std::string& _return, const std::string& principal, const std::map<std::string, std::string> & loginProperties)
 {
   send_login(principal, loginProperties);
@@ -22643,6 +30758,197 @@
   return;
 }
 
+void AccumuloProxyClient::grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  send_grantNamespacePermission(login, user, namespaceName, perm);
+  recv_grantNamespacePermission();
+}
+
+void AccumuloProxyClient::send_grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("grantNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_grantNamespacePermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.namespaceName = &namespaceName;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_grantNamespacePermission()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("grantNamespacePermission") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_grantNamespacePermission_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  return;
+}
+
+bool AccumuloProxyClient::hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  send_hasNamespacePermission(login, user, namespaceName, perm);
+  return recv_hasNamespacePermission();
+}
+
+void AccumuloProxyClient::send_hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("hasNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_hasNamespacePermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.namespaceName = &namespaceName;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+bool AccumuloProxyClient::recv_hasNamespacePermission()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("hasNamespacePermission") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  bool _return;
+  AccumuloProxy_hasNamespacePermission_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    return _return;
+  }
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasNamespacePermission failed: unknown result");
+}
+
+void AccumuloProxyClient::revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  send_revokeNamespacePermission(login, user, namespaceName, perm);
+  recv_revokeNamespacePermission();
+}
+
+void AccumuloProxyClient::send_revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("revokeNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_revokeNamespacePermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.namespaceName = &namespaceName;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_revokeNamespacePermission()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("revokeNamespacePermission") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_revokeNamespacePermission_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  return;
+}
+
 void AccumuloProxyClient::createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options)
 {
   send_createBatchScanner(login, tableName, options);
@@ -23177,7 +31483,7 @@
 void AccumuloProxyClient::send_update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
 {
   int32_t cseqid = 0;
-  oprot_->writeMessageBegin("update", ::apache::thrift::protocol::T_CALL, cseqid);
+  oprot_->writeMessageBegin("update", ::apache::thrift::protocol::T_ONEWAY, cseqid);
 
   AccumuloProxy_update_pargs args;
   args.writer = &writer;
@@ -23684,6 +31990,1310 @@
   throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getFollowing failed: unknown result");
 }
 
+void AccumuloProxyClient::systemNamespace(std::string& _return)
+{
+  send_systemNamespace();
+  recv_systemNamespace(_return);
+}
+
+void AccumuloProxyClient::send_systemNamespace()
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("systemNamespace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_systemNamespace_pargs args;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_systemNamespace(std::string& _return)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("systemNamespace") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_systemNamespace_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    // _return pointer has now been filled
+    return;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "systemNamespace failed: unknown result");
+}
+
+void AccumuloProxyClient::defaultNamespace(std::string& _return)
+{
+  send_defaultNamespace();
+  recv_defaultNamespace(_return);
+}
+
+void AccumuloProxyClient::send_defaultNamespace()
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("defaultNamespace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_defaultNamespace_pargs args;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_defaultNamespace(std::string& _return)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("defaultNamespace") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_defaultNamespace_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    // _return pointer has now been filled
+    return;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "defaultNamespace failed: unknown result");
+}
+
+void AccumuloProxyClient::listNamespaces(std::vector<std::string> & _return, const std::string& login)
+{
+  send_listNamespaces(login);
+  recv_listNamespaces(_return);
+}
+
+void AccumuloProxyClient::send_listNamespaces(const std::string& login)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("listNamespaces", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listNamespaces_pargs args;
+  args.login = &login;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_listNamespaces(std::vector<std::string> & _return)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("listNamespaces") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_listNamespaces_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    // _return pointer has now been filled
+    return;
+  }
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaces failed: unknown result");
+}
+
+bool AccumuloProxyClient::namespaceExists(const std::string& login, const std::string& namespaceName)
+{
+  send_namespaceExists(login, namespaceName);
+  return recv_namespaceExists();
+}
+
+void AccumuloProxyClient::send_namespaceExists(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("namespaceExists", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_namespaceExists_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+bool AccumuloProxyClient::recv_namespaceExists()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("namespaceExists") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  bool _return;
+  AccumuloProxy_namespaceExists_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    return _return;
+  }
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "namespaceExists failed: unknown result");
+}
+
+void AccumuloProxyClient::createNamespace(const std::string& login, const std::string& namespaceName)
+{
+  send_createNamespace(login, namespaceName);
+  recv_createNamespace();
+}
+
+void AccumuloProxyClient::send_createNamespace(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("createNamespace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_createNamespace_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_createNamespace()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("createNamespace") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_createNamespace_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  return;
+}
+
+void AccumuloProxyClient::deleteNamespace(const std::string& login, const std::string& namespaceName)
+{
+  send_deleteNamespace(login, namespaceName);
+  recv_deleteNamespace();
+}
+
+void AccumuloProxyClient::send_deleteNamespace(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("deleteNamespace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_deleteNamespace_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_deleteNamespace()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("deleteNamespace") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_deleteNamespace_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  if (result.__isset.ouch4) {
+    throw result.ouch4;
+  }
+  return;
+}
+
+void AccumuloProxyClient::renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName)
+{
+  send_renameNamespace(login, oldNamespaceName, newNamespaceName);
+  recv_renameNamespace();
+}
+
+void AccumuloProxyClient::send_renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("renameNamespace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_renameNamespace_pargs args;
+  args.login = &login;
+  args.oldNamespaceName = &oldNamespaceName;
+  args.newNamespaceName = &newNamespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_renameNamespace()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("renameNamespace") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_renameNamespace_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  if (result.__isset.ouch4) {
+    throw result.ouch4;
+  }
+  return;
+}
+
+void AccumuloProxyClient::setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value)
+{
+  send_setNamespaceProperty(login, namespaceName, property, value);
+  recv_setNamespaceProperty();
+}
+
+void AccumuloProxyClient::send_setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("setNamespaceProperty", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_setNamespaceProperty_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.property = &property;
+  args.value = &value;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_setNamespaceProperty()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("setNamespaceProperty") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_setNamespaceProperty_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  return;
+}
+
+void AccumuloProxyClient::removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property)
+{
+  send_removeNamespaceProperty(login, namespaceName, property);
+  recv_removeNamespaceProperty();
+}
+
+void AccumuloProxyClient::send_removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("removeNamespaceProperty", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_removeNamespaceProperty_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.property = &property;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_removeNamespaceProperty()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("removeNamespaceProperty") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_removeNamespaceProperty_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  return;
+}
+
+void AccumuloProxyClient::getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName)
+{
+  send_getNamespaceProperties(login, namespaceName);
+  recv_getNamespaceProperties(_return);
+}
+
+void AccumuloProxyClient::send_getNamespaceProperties(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("getNamespaceProperties", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getNamespaceProperties_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_getNamespaceProperties(std::map<std::string, std::string> & _return)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("getNamespaceProperties") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_getNamespaceProperties_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    // _return pointer has now been filled
+    return;
+  }
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getNamespaceProperties failed: unknown result");
+}
+
+void AccumuloProxyClient::namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login)
+{
+  send_namespaceIdMap(login);
+  recv_namespaceIdMap(_return);
+}
+
+void AccumuloProxyClient::send_namespaceIdMap(const std::string& login)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("namespaceIdMap", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_namespaceIdMap_pargs args;
+  args.login = &login;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_namespaceIdMap(std::map<std::string, std::string> & _return)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("namespaceIdMap") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_namespaceIdMap_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    // _return pointer has now been filled
+    return;
+  }
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "namespaceIdMap failed: unknown result");
+}
+
+void AccumuloProxyClient::attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  send_attachNamespaceIterator(login, namespaceName, setting, scopes);
+  recv_attachNamespaceIterator();
+}
+
+void AccumuloProxyClient::send_attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("attachNamespaceIterator", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_attachNamespaceIterator_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.setting = &setting;
+  args.scopes = &scopes;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_attachNamespaceIterator()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("attachNamespaceIterator") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_attachNamespaceIterator_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  return;
+}
+
+void AccumuloProxyClient::removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes)
+{
+  send_removeNamespaceIterator(login, namespaceName, name, scopes);
+  recv_removeNamespaceIterator();
+}
+
+void AccumuloProxyClient::send_removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("removeNamespaceIterator", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_removeNamespaceIterator_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.name = &name;
+  args.scopes = &scopes;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_removeNamespaceIterator()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("removeNamespaceIterator") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_removeNamespaceIterator_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  return;
+}
+
+void AccumuloProxyClient::getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope)
+{
+  send_getNamespaceIteratorSetting(login, namespaceName, name, scope);
+  recv_getNamespaceIteratorSetting(_return);
+}
+
+void AccumuloProxyClient::send_getNamespaceIteratorSetting(const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("getNamespaceIteratorSetting", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getNamespaceIteratorSetting_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.name = &name;
+  args.scope = &scope;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_getNamespaceIteratorSetting(IteratorSetting& _return)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("getNamespaceIteratorSetting") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_getNamespaceIteratorSetting_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    // _return pointer has now been filled
+    return;
+  }
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getNamespaceIteratorSetting failed: unknown result");
+}
+
+void AccumuloProxyClient::listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName)
+{
+  send_listNamespaceIterators(login, namespaceName);
+  recv_listNamespaceIterators(_return);
+}
+
+void AccumuloProxyClient::send_listNamespaceIterators(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("listNamespaceIterators", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listNamespaceIterators_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("listNamespaceIterators") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_listNamespaceIterators_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    // _return pointer has now been filled
+    return;
+  }
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaceIterators failed: unknown result");
+}
+
+void AccumuloProxyClient::checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  send_checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes);
+  recv_checkNamespaceIteratorConflicts();
+}
+
+void AccumuloProxyClient::send_checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("checkNamespaceIteratorConflicts", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_checkNamespaceIteratorConflicts_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.setting = &setting;
+  args.scopes = &scopes;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_checkNamespaceIteratorConflicts()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("checkNamespaceIteratorConflicts") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_checkNamespaceIteratorConflicts_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  return;
+}
+
+int32_t AccumuloProxyClient::addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName)
+{
+  send_addNamespaceConstraint(login, namespaceName, constraintClassName);
+  return recv_addNamespaceConstraint();
+}
+
+void AccumuloProxyClient::send_addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("addNamespaceConstraint", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_addNamespaceConstraint_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.constraintClassName = &constraintClassName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+int32_t AccumuloProxyClient::recv_addNamespaceConstraint()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("addNamespaceConstraint") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  int32_t _return;
+  AccumuloProxy_addNamespaceConstraint_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    return _return;
+  }
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "addNamespaceConstraint failed: unknown result");
+}
+
+void AccumuloProxyClient::removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id)
+{
+  send_removeNamespaceConstraint(login, namespaceName, id);
+  recv_removeNamespaceConstraint();
+}
+
+void AccumuloProxyClient::send_removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("removeNamespaceConstraint", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_removeNamespaceConstraint_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.id = &id;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_removeNamespaceConstraint()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("removeNamespaceConstraint") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_removeNamespaceConstraint_presult result;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  return;
+}
+
+void AccumuloProxyClient::listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName)
+{
+  send_listNamespaceConstraints(login, namespaceName);
+  recv_listNamespaceConstraints(_return);
+}
+
+void AccumuloProxyClient::send_listNamespaceConstraints(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("listNamespaceConstraints", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listNamespaceConstraints_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+void AccumuloProxyClient::recv_listNamespaceConstraints(std::map<std::string, int32_t> & _return)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("listNamespaceConstraints") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  AccumuloProxy_listNamespaceConstraints_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    // _return pointer has now been filled
+    return;
+  }
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaceConstraints failed: unknown result");
+}
+
+bool AccumuloProxyClient::testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName)
+{
+  send_testNamespaceClassLoad(login, namespaceName, className, asTypeName);
+  return recv_testNamespaceClassLoad();
+}
+
+void AccumuloProxyClient::send_testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName)
+{
+  int32_t cseqid = 0;
+  oprot_->writeMessageBegin("testNamespaceClassLoad", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_testNamespaceClassLoad_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.className = &className;
+  args.asTypeName = &asTypeName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+}
+
+bool AccumuloProxyClient::recv_testNamespaceClassLoad()
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  iprot_->readMessageBegin(fname, mtype, rseqid);
+  if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+    ::apache::thrift::TApplicationException x;
+    x.read(iprot_);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+    throw x;
+  }
+  if (mtype != ::apache::thrift::protocol::T_REPLY) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  if (fname.compare("testNamespaceClassLoad") != 0) {
+    iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+    iprot_->readMessageEnd();
+    iprot_->getTransport()->readEnd();
+  }
+  bool _return;
+  AccumuloProxy_testNamespaceClassLoad_presult result;
+  result.success = &_return;
+  result.read(iprot_);
+  iprot_->readMessageEnd();
+  iprot_->getTransport()->readEnd();
+
+  if (result.__isset.success) {
+    return _return;
+  }
+  if (result.__isset.ouch1) {
+    throw result.ouch1;
+  }
+  if (result.__isset.ouch2) {
+    throw result.ouch2;
+  }
+  if (result.__isset.ouch3) {
+    throw result.ouch3;
+  }
+  throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "testNamespaceClassLoad failed: unknown result");
+}
+
 bool AccumuloProxyProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
   ProcessMap::iterator pfn;
   pfn = processMap_.find(fname);
@@ -27356,6 +36966,184 @@
   }
 }
 
+void AccumuloProxyProcessor::process_grantNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.grantNamespacePermission", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.grantNamespacePermission");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.grantNamespacePermission");
+  }
+
+  AccumuloProxy_grantNamespacePermission_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.grantNamespacePermission", bytes);
+  }
+
+  AccumuloProxy_grantNamespacePermission_result result;
+  try {
+    iface_->grantNamespacePermission(args.login, args.user, args.namespaceName, args.perm);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.grantNamespacePermission");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("grantNamespacePermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.grantNamespacePermission");
+  }
+
+  oprot->writeMessageBegin("grantNamespacePermission", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.grantNamespacePermission", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_hasNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.hasNamespacePermission", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.hasNamespacePermission");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.hasNamespacePermission");
+  }
+
+  AccumuloProxy_hasNamespacePermission_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.hasNamespacePermission", bytes);
+  }
+
+  AccumuloProxy_hasNamespacePermission_result result;
+  try {
+    result.success = iface_->hasNamespacePermission(args.login, args.user, args.namespaceName, args.perm);
+    result.__isset.success = true;
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.hasNamespacePermission");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("hasNamespacePermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.hasNamespacePermission");
+  }
+
+  oprot->writeMessageBegin("hasNamespacePermission", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.hasNamespacePermission", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_revokeNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.revokeNamespacePermission", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.revokeNamespacePermission");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.revokeNamespacePermission");
+  }
+
+  AccumuloProxy_revokeNamespacePermission_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.revokeNamespacePermission", bytes);
+  }
+
+  AccumuloProxy_revokeNamespacePermission_result result;
+  try {
+    iface_->revokeNamespacePermission(args.login, args.user, args.namespaceName, args.perm);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.revokeNamespacePermission");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("revokeNamespacePermission", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.revokeNamespacePermission");
+  }
+
+  oprot->writeMessageBegin("revokeNamespacePermission", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.revokeNamespacePermission", bytes);
+  }
+}
+
 void AccumuloProxyProcessor::process_createBatchScanner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
 {
   void* ctx = NULL;
@@ -27872,7 +37660,7 @@
 
   try {
     iface_->update(args.writer, args.cells);
-  } catch (const std::exception& e) {
+  } catch (const std::exception&) {
     if (this->eventHandler_.get() != NULL) {
       this->eventHandler_->handlerError(ctx, "AccumuloProxy.update");
     }
@@ -28354,11 +38142,10425 @@
   }
 }
 
+void AccumuloProxyProcessor::process_systemNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.systemNamespace", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.systemNamespace");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.systemNamespace");
+  }
+
+  AccumuloProxy_systemNamespace_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.systemNamespace", bytes);
+  }
+
+  AccumuloProxy_systemNamespace_result result;
+  try {
+    iface_->systemNamespace(result.success);
+    result.__isset.success = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.systemNamespace");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("systemNamespace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.systemNamespace");
+  }
+
+  oprot->writeMessageBegin("systemNamespace", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.systemNamespace", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_defaultNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.defaultNamespace", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.defaultNamespace");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.defaultNamespace");
+  }
+
+  AccumuloProxy_defaultNamespace_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.defaultNamespace", bytes);
+  }
+
+  AccumuloProxy_defaultNamespace_result result;
+  try {
+    iface_->defaultNamespace(result.success);
+    result.__isset.success = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.defaultNamespace");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("defaultNamespace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.defaultNamespace");
+  }
+
+  oprot->writeMessageBegin("defaultNamespace", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.defaultNamespace", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_listNamespaces(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.listNamespaces", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listNamespaces");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.listNamespaces");
+  }
+
+  AccumuloProxy_listNamespaces_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.listNamespaces", bytes);
+  }
+
+  AccumuloProxy_listNamespaces_result result;
+  try {
+    iface_->listNamespaces(result.success, args.login);
+    result.__isset.success = true;
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listNamespaces");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("listNamespaces", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listNamespaces");
+  }
+
+  oprot->writeMessageBegin("listNamespaces", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listNamespaces", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_namespaceExists(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.namespaceExists", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.namespaceExists");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.namespaceExists");
+  }
+
+  AccumuloProxy_namespaceExists_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.namespaceExists", bytes);
+  }
+
+  AccumuloProxy_namespaceExists_result result;
+  try {
+    result.success = iface_->namespaceExists(args.login, args.namespaceName);
+    result.__isset.success = true;
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.namespaceExists");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("namespaceExists", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.namespaceExists");
+  }
+
+  oprot->writeMessageBegin("namespaceExists", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.namespaceExists", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_createNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.createNamespace", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.createNamespace");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.createNamespace");
+  }
+
+  AccumuloProxy_createNamespace_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.createNamespace", bytes);
+  }
+
+  AccumuloProxy_createNamespace_result result;
+  try {
+    iface_->createNamespace(args.login, args.namespaceName);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceExistsException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.createNamespace");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("createNamespace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.createNamespace");
+  }
+
+  oprot->writeMessageBegin("createNamespace", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.createNamespace", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_deleteNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.deleteNamespace", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.deleteNamespace");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.deleteNamespace");
+  }
+
+  AccumuloProxy_deleteNamespace_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.deleteNamespace", bytes);
+  }
+
+  AccumuloProxy_deleteNamespace_result result;
+  try {
+    iface_->deleteNamespace(args.login, args.namespaceName);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (NamespaceNotEmptyException &ouch4) {
+    result.ouch4 = ouch4;
+    result.__isset.ouch4 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.deleteNamespace");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("deleteNamespace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.deleteNamespace");
+  }
+
+  oprot->writeMessageBegin("deleteNamespace", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.deleteNamespace", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_renameNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.renameNamespace", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.renameNamespace");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.renameNamespace");
+  }
+
+  AccumuloProxy_renameNamespace_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.renameNamespace", bytes);
+  }
+
+  AccumuloProxy_renameNamespace_result result;
+  try {
+    iface_->renameNamespace(args.login, args.oldNamespaceName, args.newNamespaceName);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (NamespaceExistsException &ouch4) {
+    result.ouch4 = ouch4;
+    result.__isset.ouch4 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.renameNamespace");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("renameNamespace", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.renameNamespace");
+  }
+
+  oprot->writeMessageBegin("renameNamespace", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.renameNamespace", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_setNamespaceProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.setNamespaceProperty", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.setNamespaceProperty");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.setNamespaceProperty");
+  }
+
+  AccumuloProxy_setNamespaceProperty_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.setNamespaceProperty", bytes);
+  }
+
+  AccumuloProxy_setNamespaceProperty_result result;
+  try {
+    iface_->setNamespaceProperty(args.login, args.namespaceName, args.property, args.value);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.setNamespaceProperty");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("setNamespaceProperty", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.setNamespaceProperty");
+  }
+
+  oprot->writeMessageBegin("setNamespaceProperty", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.setNamespaceProperty", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_removeNamespaceProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.removeNamespaceProperty", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.removeNamespaceProperty");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.removeNamespaceProperty");
+  }
+
+  AccumuloProxy_removeNamespaceProperty_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.removeNamespaceProperty", bytes);
+  }
+
+  AccumuloProxy_removeNamespaceProperty_result result;
+  try {
+    iface_->removeNamespaceProperty(args.login, args.namespaceName, args.property);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.removeNamespaceProperty");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("removeNamespaceProperty", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.removeNamespaceProperty");
+  }
+
+  oprot->writeMessageBegin("removeNamespaceProperty", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.removeNamespaceProperty", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_getNamespaceProperties(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.getNamespaceProperties", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getNamespaceProperties");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.getNamespaceProperties");
+  }
+
+  AccumuloProxy_getNamespaceProperties_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.getNamespaceProperties", bytes);
+  }
+
+  AccumuloProxy_getNamespaceProperties_result result;
+  try {
+    iface_->getNamespaceProperties(result.success, args.login, args.namespaceName);
+    result.__isset.success = true;
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getNamespaceProperties");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("getNamespaceProperties", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getNamespaceProperties");
+  }
+
+  oprot->writeMessageBegin("getNamespaceProperties", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getNamespaceProperties", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_namespaceIdMap(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.namespaceIdMap", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.namespaceIdMap");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.namespaceIdMap");
+  }
+
+  AccumuloProxy_namespaceIdMap_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.namespaceIdMap", bytes);
+  }
+
+  AccumuloProxy_namespaceIdMap_result result;
+  try {
+    iface_->namespaceIdMap(result.success, args.login);
+    result.__isset.success = true;
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.namespaceIdMap");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("namespaceIdMap", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.namespaceIdMap");
+  }
+
+  oprot->writeMessageBegin("namespaceIdMap", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.namespaceIdMap", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_attachNamespaceIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.attachNamespaceIterator", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.attachNamespaceIterator");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.attachNamespaceIterator");
+  }
+
+  AccumuloProxy_attachNamespaceIterator_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.attachNamespaceIterator", bytes);
+  }
+
+  AccumuloProxy_attachNamespaceIterator_result result;
+  try {
+    iface_->attachNamespaceIterator(args.login, args.namespaceName, args.setting, args.scopes);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.attachNamespaceIterator");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("attachNamespaceIterator", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.attachNamespaceIterator");
+  }
+
+  oprot->writeMessageBegin("attachNamespaceIterator", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.attachNamespaceIterator", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_removeNamespaceIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.removeNamespaceIterator", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.removeNamespaceIterator");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.removeNamespaceIterator");
+  }
+
+  AccumuloProxy_removeNamespaceIterator_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.removeNamespaceIterator", bytes);
+  }
+
+  AccumuloProxy_removeNamespaceIterator_result result;
+  try {
+    iface_->removeNamespaceIterator(args.login, args.namespaceName, args.name, args.scopes);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.removeNamespaceIterator");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("removeNamespaceIterator", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.removeNamespaceIterator");
+  }
+
+  oprot->writeMessageBegin("removeNamespaceIterator", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.removeNamespaceIterator", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_getNamespaceIteratorSetting(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.getNamespaceIteratorSetting", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.getNamespaceIteratorSetting");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.getNamespaceIteratorSetting");
+  }
+
+  AccumuloProxy_getNamespaceIteratorSetting_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.getNamespaceIteratorSetting", bytes);
+  }
+
+  AccumuloProxy_getNamespaceIteratorSetting_result result;
+  try {
+    iface_->getNamespaceIteratorSetting(result.success, args.login, args.namespaceName, args.name, args.scope);
+    result.__isset.success = true;
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.getNamespaceIteratorSetting");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("getNamespaceIteratorSetting", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.getNamespaceIteratorSetting");
+  }
+
+  oprot->writeMessageBegin("getNamespaceIteratorSetting", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.getNamespaceIteratorSetting", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_listNamespaceIterators(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.listNamespaceIterators", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listNamespaceIterators");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.listNamespaceIterators");
+  }
+
+  AccumuloProxy_listNamespaceIterators_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.listNamespaceIterators", bytes);
+  }
+
+  AccumuloProxy_listNamespaceIterators_result result;
+  try {
+    iface_->listNamespaceIterators(result.success, args.login, args.namespaceName);
+    result.__isset.success = true;
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listNamespaceIterators");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("listNamespaceIterators", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listNamespaceIterators");
+  }
+
+  oprot->writeMessageBegin("listNamespaceIterators", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listNamespaceIterators", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_checkNamespaceIteratorConflicts(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.checkNamespaceIteratorConflicts", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.checkNamespaceIteratorConflicts");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.checkNamespaceIteratorConflicts");
+  }
+
+  AccumuloProxy_checkNamespaceIteratorConflicts_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.checkNamespaceIteratorConflicts", bytes);
+  }
+
+  AccumuloProxy_checkNamespaceIteratorConflicts_result result;
+  try {
+    iface_->checkNamespaceIteratorConflicts(args.login, args.namespaceName, args.setting, args.scopes);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.checkNamespaceIteratorConflicts");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("checkNamespaceIteratorConflicts", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.checkNamespaceIteratorConflicts");
+  }
+
+  oprot->writeMessageBegin("checkNamespaceIteratorConflicts", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.checkNamespaceIteratorConflicts", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_addNamespaceConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.addNamespaceConstraint", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.addNamespaceConstraint");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.addNamespaceConstraint");
+  }
+
+  AccumuloProxy_addNamespaceConstraint_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.addNamespaceConstraint", bytes);
+  }
+
+  AccumuloProxy_addNamespaceConstraint_result result;
+  try {
+    result.success = iface_->addNamespaceConstraint(args.login, args.namespaceName, args.constraintClassName);
+    result.__isset.success = true;
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.addNamespaceConstraint");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("addNamespaceConstraint", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.addNamespaceConstraint");
+  }
+
+  oprot->writeMessageBegin("addNamespaceConstraint", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.addNamespaceConstraint", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_removeNamespaceConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.removeNamespaceConstraint", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.removeNamespaceConstraint");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.removeNamespaceConstraint");
+  }
+
+  AccumuloProxy_removeNamespaceConstraint_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.removeNamespaceConstraint", bytes);
+  }
+
+  AccumuloProxy_removeNamespaceConstraint_result result;
+  try {
+    iface_->removeNamespaceConstraint(args.login, args.namespaceName, args.id);
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.removeNamespaceConstraint");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("removeNamespaceConstraint", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.removeNamespaceConstraint");
+  }
+
+  oprot->writeMessageBegin("removeNamespaceConstraint", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.removeNamespaceConstraint", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_listNamespaceConstraints(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.listNamespaceConstraints", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.listNamespaceConstraints");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.listNamespaceConstraints");
+  }
+
+  AccumuloProxy_listNamespaceConstraints_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.listNamespaceConstraints", bytes);
+  }
+
+  AccumuloProxy_listNamespaceConstraints_result result;
+  try {
+    iface_->listNamespaceConstraints(result.success, args.login, args.namespaceName);
+    result.__isset.success = true;
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.listNamespaceConstraints");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("listNamespaceConstraints", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.listNamespaceConstraints");
+  }
+
+  oprot->writeMessageBegin("listNamespaceConstraints", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.listNamespaceConstraints", bytes);
+  }
+}
+
+void AccumuloProxyProcessor::process_testNamespaceClassLoad(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
+{
+  void* ctx = NULL;
+  if (this->eventHandler_.get() != NULL) {
+    ctx = this->eventHandler_->getContext("AccumuloProxy.testNamespaceClassLoad", callContext);
+  }
+  ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "AccumuloProxy.testNamespaceClassLoad");
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preRead(ctx, "AccumuloProxy.testNamespaceClassLoad");
+  }
+
+  AccumuloProxy_testNamespaceClassLoad_args args;
+  args.read(iprot);
+  iprot->readMessageEnd();
+  uint32_t bytes = iprot->getTransport()->readEnd();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postRead(ctx, "AccumuloProxy.testNamespaceClassLoad", bytes);
+  }
+
+  AccumuloProxy_testNamespaceClassLoad_result result;
+  try {
+    result.success = iface_->testNamespaceClassLoad(args.login, args.namespaceName, args.className, args.asTypeName);
+    result.__isset.success = true;
+  } catch (AccumuloException &ouch1) {
+    result.ouch1 = ouch1;
+    result.__isset.ouch1 = true;
+  } catch (AccumuloSecurityException &ouch2) {
+    result.ouch2 = ouch2;
+    result.__isset.ouch2 = true;
+  } catch (NamespaceNotFoundException &ouch3) {
+    result.ouch3 = ouch3;
+    result.__isset.ouch3 = true;
+  } catch (const std::exception& e) {
+    if (this->eventHandler_.get() != NULL) {
+      this->eventHandler_->handlerError(ctx, "AccumuloProxy.testNamespaceClassLoad");
+    }
+
+    ::apache::thrift::TApplicationException x(e.what());
+    oprot->writeMessageBegin("testNamespaceClassLoad", ::apache::thrift::protocol::T_EXCEPTION, seqid);
+    x.write(oprot);
+    oprot->writeMessageEnd();
+    oprot->getTransport()->writeEnd();
+    oprot->getTransport()->flush();
+    return;
+  }
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->preWrite(ctx, "AccumuloProxy.testNamespaceClassLoad");
+  }
+
+  oprot->writeMessageBegin("testNamespaceClassLoad", ::apache::thrift::protocol::T_REPLY, seqid);
+  result.write(oprot);
+  oprot->writeMessageEnd();
+  bytes = oprot->getTransport()->writeEnd();
+  oprot->getTransport()->flush();
+
+  if (this->eventHandler_.get() != NULL) {
+    this->eventHandler_->postWrite(ctx, "AccumuloProxy.testNamespaceClassLoad", bytes);
+  }
+}
+
 ::boost::shared_ptr< ::apache::thrift::TProcessor > AccumuloProxyProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
   ::apache::thrift::ReleaseHandler< AccumuloProxyIfFactory > cleanup(handlerFactory_);
   ::boost::shared_ptr< AccumuloProxyIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
   ::boost::shared_ptr< ::apache::thrift::TProcessor > processor(new AccumuloProxyProcessor(handler));
   return processor;
 }
+
+void AccumuloProxyConcurrentClient::login(std::string& _return, const std::string& principal, const std::map<std::string, std::string> & loginProperties)
+{
+  int32_t seqid = send_login(principal, loginProperties);
+  recv_login(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_login(const std::string& principal, const std::map<std::string, std::string> & loginProperties)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("login", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_login_pargs args;
+  args.principal = &principal;
+  args.loginProperties = &loginProperties;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_login(std::string& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("login") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_login_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "login failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+int32_t AccumuloProxyConcurrentClient::addConstraint(const std::string& login, const std::string& tableName, const std::string& constraintClassName)
+{
+  int32_t seqid = send_addConstraint(login, tableName, constraintClassName);
+  return recv_addConstraint(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_addConstraint(const std::string& login, const std::string& tableName, const std::string& constraintClassName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("addConstraint", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_addConstraint_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.constraintClassName = &constraintClassName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+int32_t AccumuloProxyConcurrentClient::recv_addConstraint(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("addConstraint") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      int32_t _return;
+      AccumuloProxy_addConstraint_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "addConstraint failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::addSplits(const std::string& login, const std::string& tableName, const std::set<std::string> & splits)
+{
+  int32_t seqid = send_addSplits(login, tableName, splits);
+  recv_addSplits(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_addSplits(const std::string& login, const std::string& tableName, const std::set<std::string> & splits)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("addSplits", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_addSplits_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.splits = &splits;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_addSplits(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("addSplits") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_addSplits_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::attachIterator(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t seqid = send_attachIterator(login, tableName, setting, scopes);
+  recv_attachIterator(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_attachIterator(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("attachIterator", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_attachIterator_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.setting = &setting;
+  args.scopes = &scopes;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_attachIterator(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("attachIterator") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_attachIterator_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::checkIteratorConflicts(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t seqid = send_checkIteratorConflicts(login, tableName, setting, scopes);
+  recv_checkIteratorConflicts(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_checkIteratorConflicts(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("checkIteratorConflicts", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_checkIteratorConflicts_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.setting = &setting;
+  args.scopes = &scopes;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_checkIteratorConflicts(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("checkIteratorConflicts") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_checkIteratorConflicts_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::clearLocatorCache(const std::string& login, const std::string& tableName)
+{
+  int32_t seqid = send_clearLocatorCache(login, tableName);
+  recv_clearLocatorCache(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_clearLocatorCache(const std::string& login, const std::string& tableName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("clearLocatorCache", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_clearLocatorCache_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_clearLocatorCache(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("clearLocatorCache") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_clearLocatorCache_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::cloneTable(const std::string& login, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude)
+{
+  int32_t seqid = send_cloneTable(login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude);
+  recv_cloneTable(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_cloneTable(const std::string& login, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("cloneTable", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_cloneTable_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.newTableName = &newTableName;
+  args.flush = &flush;
+  args.propertiesToSet = &propertiesToSet;
+  args.propertiesToExclude = &propertiesToExclude;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_cloneTable(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("cloneTable") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_cloneTable_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      if (result.__isset.ouch4) {
+        sentry.commit();
+        throw result.ouch4;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::compactTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const CompactionStrategyConfig& compactionStrategy)
+{
+  int32_t seqid = send_compactTable(login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy);
+  recv_compactTable(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_compactTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const CompactionStrategyConfig& compactionStrategy)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("compactTable", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_compactTable_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.startRow = &startRow;
+  args.endRow = &endRow;
+  args.iterators = &iterators;
+  args.flush = &flush;
+  args.wait = &wait;
+  args.compactionStrategy = &compactionStrategy;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_compactTable(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("compactTable") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_compactTable_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::cancelCompaction(const std::string& login, const std::string& tableName)
+{
+  int32_t seqid = send_cancelCompaction(login, tableName);
+  recv_cancelCompaction(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_cancelCompaction(const std::string& login, const std::string& tableName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("cancelCompaction", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_cancelCompaction_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_cancelCompaction(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("cancelCompaction") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_cancelCompaction_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::createTable(const std::string& login, const std::string& tableName, const bool versioningIter, const TimeType::type type)
+{
+  int32_t seqid = send_createTable(login, tableName, versioningIter, type);
+  recv_createTable(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_createTable(const std::string& login, const std::string& tableName, const bool versioningIter, const TimeType::type type)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("createTable", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_createTable_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.versioningIter = &versioningIter;
+  args.type = &type;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_createTable(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("createTable") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_createTable_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::deleteTable(const std::string& login, const std::string& tableName)
+{
+  int32_t seqid = send_deleteTable(login, tableName);
+  recv_deleteTable(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_deleteTable(const std::string& login, const std::string& tableName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("deleteTable", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_deleteTable_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_deleteTable(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("deleteTable") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_deleteTable_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::deleteRows(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow)
+{
+  int32_t seqid = send_deleteRows(login, tableName, startRow, endRow);
+  recv_deleteRows(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_deleteRows(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("deleteRows", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_deleteRows_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.startRow = &startRow;
+  args.endRow = &endRow;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_deleteRows(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("deleteRows") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_deleteRows_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::exportTable(const std::string& login, const std::string& tableName, const std::string& exportDir)
+{
+  int32_t seqid = send_exportTable(login, tableName, exportDir);
+  recv_exportTable(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_exportTable(const std::string& login, const std::string& tableName, const std::string& exportDir)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("exportTable", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_exportTable_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.exportDir = &exportDir;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_exportTable(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("exportTable") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_exportTable_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::flushTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait)
+{
+  int32_t seqid = send_flushTable(login, tableName, startRow, endRow, wait);
+  recv_flushTable(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_flushTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("flushTable", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_flushTable_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.startRow = &startRow;
+  args.endRow = &endRow;
+  args.wait = &wait;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_flushTable(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("flushTable") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_flushTable_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getDiskUsage(std::vector<DiskUsage> & _return, const std::string& login, const std::set<std::string> & tables)
+{
+  int32_t seqid = send_getDiskUsage(login, tables);
+  recv_getDiskUsage(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getDiskUsage(const std::string& login, const std::set<std::string> & tables)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getDiskUsage", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getDiskUsage_pargs args;
+  args.login = &login;
+  args.tables = &tables;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getDiskUsage(std::vector<DiskUsage> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getDiskUsage") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getDiskUsage_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getDiskUsage failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const std::string& login, const std::string& tableName)
+{
+  int32_t seqid = send_getLocalityGroups(login, tableName);
+  recv_getLocalityGroups(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getLocalityGroups(const std::string& login, const std::string& tableName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getLocalityGroups", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getLocalityGroups_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getLocalityGroups") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getLocalityGroups_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getLocalityGroups failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope)
+{
+  int32_t seqid = send_getIteratorSetting(login, tableName, iteratorName, scope);
+  recv_getIteratorSetting(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getIteratorSetting(const std::string& login, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getIteratorSetting", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getIteratorSetting_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.iteratorName = &iteratorName;
+  args.scope = &scope;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getIteratorSetting(IteratorSetting& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getIteratorSetting") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getIteratorSetting_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getIteratorSetting failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getMaxRow(std::string& _return, const std::string& login, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive)
+{
+  int32_t seqid = send_getMaxRow(login, tableName, auths, startRow, startInclusive, endRow, endInclusive);
+  recv_getMaxRow(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getMaxRow(const std::string& login, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getMaxRow", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getMaxRow_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.auths = &auths;
+  args.startRow = &startRow;
+  args.startInclusive = &startInclusive;
+  args.endRow = &endRow;
+  args.endInclusive = &endInclusive;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getMaxRow(std::string& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getMaxRow") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getMaxRow_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getMaxRow failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getTableProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& tableName)
+{
+  int32_t seqid = send_getTableProperties(login, tableName);
+  recv_getTableProperties(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getTableProperties(const std::string& login, const std::string& tableName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getTableProperties", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getTableProperties_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getTableProperties(std::map<std::string, std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getTableProperties") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getTableProperties_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getTableProperties failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::importDirectory(const std::string& login, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime)
+{
+  int32_t seqid = send_importDirectory(login, tableName, importDir, failureDir, setTime);
+  recv_importDirectory(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_importDirectory(const std::string& login, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("importDirectory", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_importDirectory_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.importDir = &importDir;
+  args.failureDir = &failureDir;
+  args.setTime = &setTime;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_importDirectory(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("importDirectory") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_importDirectory_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      if (result.__isset.ouch4) {
+        sentry.commit();
+        throw result.ouch4;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::importTable(const std::string& login, const std::string& tableName, const std::string& importDir)
+{
+  int32_t seqid = send_importTable(login, tableName, importDir);
+  recv_importTable(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_importTable(const std::string& login, const std::string& tableName, const std::string& importDir)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("importTable", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_importTable_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.importDir = &importDir;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_importTable(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("importTable") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_importTable_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::listSplits(std::vector<std::string> & _return, const std::string& login, const std::string& tableName, const int32_t maxSplits)
+{
+  int32_t seqid = send_listSplits(login, tableName, maxSplits);
+  recv_listSplits(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_listSplits(const std::string& login, const std::string& tableName, const int32_t maxSplits)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("listSplits", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listSplits_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.maxSplits = &maxSplits;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_listSplits(std::vector<std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("listSplits") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_listSplits_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listSplits failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::listTables(std::set<std::string> & _return, const std::string& login)
+{
+  int32_t seqid = send_listTables(login);
+  recv_listTables(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_listTables(const std::string& login)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("listTables", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listTables_pargs args;
+  args.login = &login;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_listTables(std::set<std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("listTables") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_listTables_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listTables failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& tableName)
+{
+  int32_t seqid = send_listIterators(login, tableName);
+  recv_listIterators(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_listIterators(const std::string& login, const std::string& tableName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("listIterators", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listIterators_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("listIterators") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_listIterators_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listIterators failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::listConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& tableName)
+{
+  int32_t seqid = send_listConstraints(login, tableName);
+  recv_listConstraints(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_listConstraints(const std::string& login, const std::string& tableName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("listConstraints", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listConstraints_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_listConstraints(std::map<std::string, int32_t> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("listConstraints") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_listConstraints_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listConstraints failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::mergeTablets(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow)
+{
+  int32_t seqid = send_mergeTablets(login, tableName, startRow, endRow);
+  recv_mergeTablets(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_mergeTablets(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("mergeTablets", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_mergeTablets_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.startRow = &startRow;
+  args.endRow = &endRow;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_mergeTablets(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("mergeTablets") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_mergeTablets_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::offlineTable(const std::string& login, const std::string& tableName, const bool wait)
+{
+  int32_t seqid = send_offlineTable(login, tableName, wait);
+  recv_offlineTable(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_offlineTable(const std::string& login, const std::string& tableName, const bool wait)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("offlineTable", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_offlineTable_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.wait = &wait;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_offlineTable(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("offlineTable") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_offlineTable_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::onlineTable(const std::string& login, const std::string& tableName, const bool wait)
+{
+  int32_t seqid = send_onlineTable(login, tableName, wait);
+  recv_onlineTable(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_onlineTable(const std::string& login, const std::string& tableName, const bool wait)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("onlineTable", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_onlineTable_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.wait = &wait;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_onlineTable(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("onlineTable") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_onlineTable_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::removeConstraint(const std::string& login, const std::string& tableName, const int32_t constraint)
+{
+  int32_t seqid = send_removeConstraint(login, tableName, constraint);
+  recv_removeConstraint(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_removeConstraint(const std::string& login, const std::string& tableName, const int32_t constraint)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("removeConstraint", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_removeConstraint_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.constraint = &constraint;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_removeConstraint(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("removeConstraint") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_removeConstraint_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::removeIterator(const std::string& login, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t seqid = send_removeIterator(login, tableName, iterName, scopes);
+  recv_removeIterator(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_removeIterator(const std::string& login, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("removeIterator", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_removeIterator_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.iterName = &iterName;
+  args.scopes = &scopes;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_removeIterator(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("removeIterator") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_removeIterator_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::removeTableProperty(const std::string& login, const std::string& tableName, const std::string& property)
+{
+  int32_t seqid = send_removeTableProperty(login, tableName, property);
+  recv_removeTableProperty(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_removeTableProperty(const std::string& login, const std::string& tableName, const std::string& property)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("removeTableProperty", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_removeTableProperty_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.property = &property;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_removeTableProperty(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("removeTableProperty") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_removeTableProperty_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::renameTable(const std::string& login, const std::string& oldTableName, const std::string& newTableName)
+{
+  int32_t seqid = send_renameTable(login, oldTableName, newTableName);
+  recv_renameTable(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_renameTable(const std::string& login, const std::string& oldTableName, const std::string& newTableName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("renameTable", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_renameTable_pargs args;
+  args.login = &login;
+  args.oldTableName = &oldTableName;
+  args.newTableName = &newTableName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_renameTable(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("renameTable") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_renameTable_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      if (result.__isset.ouch4) {
+        sentry.commit();
+        throw result.ouch4;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::setLocalityGroups(const std::string& login, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups)
+{
+  int32_t seqid = send_setLocalityGroups(login, tableName, groups);
+  recv_setLocalityGroups(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_setLocalityGroups(const std::string& login, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("setLocalityGroups", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_setLocalityGroups_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.groups = &groups;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_setLocalityGroups(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("setLocalityGroups") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_setLocalityGroups_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::setTableProperty(const std::string& login, const std::string& tableName, const std::string& property, const std::string& value)
+{
+  int32_t seqid = send_setTableProperty(login, tableName, property, value);
+  recv_setTableProperty(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_setTableProperty(const std::string& login, const std::string& tableName, const std::string& property, const std::string& value)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("setTableProperty", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_setTableProperty_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.property = &property;
+  args.value = &value;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_setTableProperty(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("setTableProperty") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_setTableProperty_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::splitRangeByTablets(std::set<Range> & _return, const std::string& login, const std::string& tableName, const Range& range, const int32_t maxSplits)
+{
+  int32_t seqid = send_splitRangeByTablets(login, tableName, range, maxSplits);
+  recv_splitRangeByTablets(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_splitRangeByTablets(const std::string& login, const std::string& tableName, const Range& range, const int32_t maxSplits)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("splitRangeByTablets", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_splitRangeByTablets_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.range = &range;
+  args.maxSplits = &maxSplits;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_splitRangeByTablets(std::set<Range> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("splitRangeByTablets") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_splitRangeByTablets_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "splitRangeByTablets failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+bool AccumuloProxyConcurrentClient::tableExists(const std::string& login, const std::string& tableName)
+{
+  int32_t seqid = send_tableExists(login, tableName);
+  return recv_tableExists(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_tableExists(const std::string& login, const std::string& tableName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("tableExists", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_tableExists_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+bool AccumuloProxyConcurrentClient::recv_tableExists(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("tableExists") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      bool _return;
+      AccumuloProxy_tableExists_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "tableExists failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::tableIdMap(std::map<std::string, std::string> & _return, const std::string& login)
+{
+  int32_t seqid = send_tableIdMap(login);
+  recv_tableIdMap(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_tableIdMap(const std::string& login)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("tableIdMap", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_tableIdMap_pargs args;
+  args.login = &login;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_tableIdMap(std::map<std::string, std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("tableIdMap") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_tableIdMap_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "tableIdMap failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+bool AccumuloProxyConcurrentClient::testTableClassLoad(const std::string& login, const std::string& tableName, const std::string& className, const std::string& asTypeName)
+{
+  int32_t seqid = send_testTableClassLoad(login, tableName, className, asTypeName);
+  return recv_testTableClassLoad(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_testTableClassLoad(const std::string& login, const std::string& tableName, const std::string& className, const std::string& asTypeName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("testTableClassLoad", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_testTableClassLoad_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.className = &className;
+  args.asTypeName = &asTypeName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+bool AccumuloProxyConcurrentClient::recv_testTableClassLoad(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("testTableClassLoad") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      bool _return;
+      AccumuloProxy_testTableClassLoad_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "testTableClassLoad failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::pingTabletServer(const std::string& login, const std::string& tserver)
+{
+  int32_t seqid = send_pingTabletServer(login, tserver);
+  recv_pingTabletServer(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_pingTabletServer(const std::string& login, const std::string& tserver)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("pingTabletServer", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_pingTabletServer_pargs args;
+  args.login = &login;
+  args.tserver = &tserver;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_pingTabletServer(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("pingTabletServer") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_pingTabletServer_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getActiveScans(std::vector<ActiveScan> & _return, const std::string& login, const std::string& tserver)
+{
+  int32_t seqid = send_getActiveScans(login, tserver);
+  recv_getActiveScans(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getActiveScans(const std::string& login, const std::string& tserver)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getActiveScans", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getActiveScans_pargs args;
+  args.login = &login;
+  args.tserver = &tserver;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getActiveScans(std::vector<ActiveScan> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getActiveScans") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getActiveScans_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getActiveScans failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getActiveCompactions(std::vector<ActiveCompaction> & _return, const std::string& login, const std::string& tserver)
+{
+  int32_t seqid = send_getActiveCompactions(login, tserver);
+  recv_getActiveCompactions(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getActiveCompactions(const std::string& login, const std::string& tserver)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getActiveCompactions", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getActiveCompactions_pargs args;
+  args.login = &login;
+  args.tserver = &tserver;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getActiveCompactions(std::vector<ActiveCompaction> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getActiveCompactions") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getActiveCompactions_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getActiveCompactions failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getSiteConfiguration(std::map<std::string, std::string> & _return, const std::string& login)
+{
+  int32_t seqid = send_getSiteConfiguration(login);
+  recv_getSiteConfiguration(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getSiteConfiguration(const std::string& login)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getSiteConfiguration", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getSiteConfiguration_pargs args;
+  args.login = &login;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getSiteConfiguration(std::map<std::string, std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getSiteConfiguration") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getSiteConfiguration_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getSiteConfiguration failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getSystemConfiguration(std::map<std::string, std::string> & _return, const std::string& login)
+{
+  int32_t seqid = send_getSystemConfiguration(login);
+  recv_getSystemConfiguration(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getSystemConfiguration(const std::string& login)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getSystemConfiguration", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getSystemConfiguration_pargs args;
+  args.login = &login;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getSystemConfiguration(std::map<std::string, std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getSystemConfiguration") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getSystemConfiguration_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getSystemConfiguration failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getTabletServers(std::vector<std::string> & _return, const std::string& login)
+{
+  int32_t seqid = send_getTabletServers(login);
+  recv_getTabletServers(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getTabletServers(const std::string& login)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getTabletServers", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getTabletServers_pargs args;
+  args.login = &login;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getTabletServers(std::vector<std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getTabletServers") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getTabletServers_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getTabletServers failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::removeProperty(const std::string& login, const std::string& property)
+{
+  int32_t seqid = send_removeProperty(login, property);
+  recv_removeProperty(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_removeProperty(const std::string& login, const std::string& property)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("removeProperty", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_removeProperty_pargs args;
+  args.login = &login;
+  args.property = &property;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_removeProperty(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("removeProperty") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_removeProperty_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::setProperty(const std::string& login, const std::string& property, const std::string& value)
+{
+  int32_t seqid = send_setProperty(login, property, value);
+  recv_setProperty(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_setProperty(const std::string& login, const std::string& property, const std::string& value)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("setProperty", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_setProperty_pargs args;
+  args.login = &login;
+  args.property = &property;
+  args.value = &value;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_setProperty(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("setProperty") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_setProperty_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+bool AccumuloProxyConcurrentClient::testClassLoad(const std::string& login, const std::string& className, const std::string& asTypeName)
+{
+  int32_t seqid = send_testClassLoad(login, className, asTypeName);
+  return recv_testClassLoad(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_testClassLoad(const std::string& login, const std::string& className, const std::string& asTypeName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("testClassLoad", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_testClassLoad_pargs args;
+  args.login = &login;
+  args.className = &className;
+  args.asTypeName = &asTypeName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+bool AccumuloProxyConcurrentClient::recv_testClassLoad(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("testClassLoad") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      bool _return;
+      AccumuloProxy_testClassLoad_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "testClassLoad failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+bool AccumuloProxyConcurrentClient::authenticateUser(const std::string& login, const std::string& user, const std::map<std::string, std::string> & properties)
+{
+  int32_t seqid = send_authenticateUser(login, user, properties);
+  return recv_authenticateUser(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_authenticateUser(const std::string& login, const std::string& user, const std::map<std::string, std::string> & properties)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("authenticateUser", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_authenticateUser_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.properties = &properties;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+bool AccumuloProxyConcurrentClient::recv_authenticateUser(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("authenticateUser") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      bool _return;
+      AccumuloProxy_authenticateUser_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "authenticateUser failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::changeUserAuthorizations(const std::string& login, const std::string& user, const std::set<std::string> & authorizations)
+{
+  int32_t seqid = send_changeUserAuthorizations(login, user, authorizations);
+  recv_changeUserAuthorizations(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_changeUserAuthorizations(const std::string& login, const std::string& user, const std::set<std::string> & authorizations)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("changeUserAuthorizations", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_changeUserAuthorizations_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.authorizations = &authorizations;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_changeUserAuthorizations(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("changeUserAuthorizations") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_changeUserAuthorizations_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::changeLocalUserPassword(const std::string& login, const std::string& user, const std::string& password)
+{
+  int32_t seqid = send_changeLocalUserPassword(login, user, password);
+  recv_changeLocalUserPassword(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_changeLocalUserPassword(const std::string& login, const std::string& user, const std::string& password)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("changeLocalUserPassword", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_changeLocalUserPassword_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.password = &password;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_changeLocalUserPassword(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("changeLocalUserPassword") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_changeLocalUserPassword_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::createLocalUser(const std::string& login, const std::string& user, const std::string& password)
+{
+  int32_t seqid = send_createLocalUser(login, user, password);
+  recv_createLocalUser(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_createLocalUser(const std::string& login, const std::string& user, const std::string& password)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("createLocalUser", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_createLocalUser_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.password = &password;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_createLocalUser(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("createLocalUser") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_createLocalUser_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::dropLocalUser(const std::string& login, const std::string& user)
+{
+  int32_t seqid = send_dropLocalUser(login, user);
+  recv_dropLocalUser(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_dropLocalUser(const std::string& login, const std::string& user)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("dropLocalUser", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_dropLocalUser_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_dropLocalUser(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("dropLocalUser") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_dropLocalUser_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getUserAuthorizations(std::vector<std::string> & _return, const std::string& login, const std::string& user)
+{
+  int32_t seqid = send_getUserAuthorizations(login, user);
+  recv_getUserAuthorizations(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getUserAuthorizations(const std::string& login, const std::string& user)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getUserAuthorizations", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getUserAuthorizations_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getUserAuthorizations(std::vector<std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getUserAuthorizations") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getUserAuthorizations_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getUserAuthorizations failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::grantSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm)
+{
+  int32_t seqid = send_grantSystemPermission(login, user, perm);
+  recv_grantSystemPermission(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_grantSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("grantSystemPermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_grantSystemPermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_grantSystemPermission(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("grantSystemPermission") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_grantSystemPermission_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::grantTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm)
+{
+  int32_t seqid = send_grantTablePermission(login, user, table, perm);
+  recv_grantTablePermission(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_grantTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("grantTablePermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_grantTablePermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.table = &table;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_grantTablePermission(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("grantTablePermission") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_grantTablePermission_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+bool AccumuloProxyConcurrentClient::hasSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm)
+{
+  int32_t seqid = send_hasSystemPermission(login, user, perm);
+  return recv_hasSystemPermission(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_hasSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("hasSystemPermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_hasSystemPermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+bool AccumuloProxyConcurrentClient::recv_hasSystemPermission(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("hasSystemPermission") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      bool _return;
+      AccumuloProxy_hasSystemPermission_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasSystemPermission failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+bool AccumuloProxyConcurrentClient::hasTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm)
+{
+  int32_t seqid = send_hasTablePermission(login, user, table, perm);
+  return recv_hasTablePermission(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_hasTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("hasTablePermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_hasTablePermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.table = &table;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+bool AccumuloProxyConcurrentClient::recv_hasTablePermission(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("hasTablePermission") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      bool _return;
+      AccumuloProxy_hasTablePermission_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasTablePermission failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::listLocalUsers(std::set<std::string> & _return, const std::string& login)
+{
+  int32_t seqid = send_listLocalUsers(login);
+  recv_listLocalUsers(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_listLocalUsers(const std::string& login)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("listLocalUsers", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listLocalUsers_pargs args;
+  args.login = &login;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_listLocalUsers(std::set<std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("listLocalUsers") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_listLocalUsers_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listLocalUsers failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm)
+{
+  int32_t seqid = send_revokeSystemPermission(login, user, perm);
+  recv_revokeSystemPermission(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("revokeSystemPermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_revokeSystemPermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_revokeSystemPermission(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("revokeSystemPermission") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_revokeSystemPermission_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm)
+{
+  int32_t seqid = send_revokeTablePermission(login, user, table, perm);
+  recv_revokeTablePermission(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("revokeTablePermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_revokeTablePermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.table = &table;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_revokeTablePermission(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("revokeTablePermission") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_revokeTablePermission_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  int32_t seqid = send_grantNamespacePermission(login, user, namespaceName, perm);
+  recv_grantNamespacePermission(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("grantNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_grantNamespacePermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.namespaceName = &namespaceName;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_grantNamespacePermission(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("grantNamespacePermission") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_grantNamespacePermission_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+bool AccumuloProxyConcurrentClient::hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  int32_t seqid = send_hasNamespacePermission(login, user, namespaceName, perm);
+  return recv_hasNamespacePermission(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("hasNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_hasNamespacePermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.namespaceName = &namespaceName;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+bool AccumuloProxyConcurrentClient::recv_hasNamespacePermission(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("hasNamespacePermission") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      bool _return;
+      AccumuloProxy_hasNamespacePermission_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasNamespacePermission failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  int32_t seqid = send_revokeNamespacePermission(login, user, namespaceName, perm);
+  recv_revokeNamespacePermission(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("revokeNamespacePermission", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_revokeNamespacePermission_pargs args;
+  args.login = &login;
+  args.user = &user;
+  args.namespaceName = &namespaceName;
+  args.perm = &perm;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_revokeNamespacePermission(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("revokeNamespacePermission") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_revokeNamespacePermission_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options)
+{
+  int32_t seqid = send_createBatchScanner(login, tableName, options);
+  recv_createBatchScanner(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_createBatchScanner(const std::string& login, const std::string& tableName, const BatchScanOptions& options)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("createBatchScanner", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_createBatchScanner_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.options = &options;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_createBatchScanner(std::string& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("createBatchScanner") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_createBatchScanner_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createBatchScanner failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::createScanner(std::string& _return, const std::string& login, const std::string& tableName, const ScanOptions& options)
+{
+  int32_t seqid = send_createScanner(login, tableName, options);
+  recv_createScanner(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_createScanner(const std::string& login, const std::string& tableName, const ScanOptions& options)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("createScanner", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_createScanner_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.options = &options;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_createScanner(std::string& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("createScanner") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_createScanner_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createScanner failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+bool AccumuloProxyConcurrentClient::hasNext(const std::string& scanner)
+{
+  int32_t seqid = send_hasNext(scanner);
+  return recv_hasNext(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_hasNext(const std::string& scanner)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("hasNext", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_hasNext_pargs args;
+  args.scanner = &scanner;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+bool AccumuloProxyConcurrentClient::recv_hasNext(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("hasNext") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      bool _return;
+      AccumuloProxy_hasNext_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "hasNext failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::nextEntry(KeyValueAndPeek& _return, const std::string& scanner)
+{
+  int32_t seqid = send_nextEntry(scanner);
+  recv_nextEntry(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_nextEntry(const std::string& scanner)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("nextEntry", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_nextEntry_pargs args;
+  args.scanner = &scanner;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_nextEntry(KeyValueAndPeek& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("nextEntry") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_nextEntry_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "nextEntry failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::nextK(ScanResult& _return, const std::string& scanner, const int32_t k)
+{
+  int32_t seqid = send_nextK(scanner, k);
+  recv_nextK(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_nextK(const std::string& scanner, const int32_t k)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("nextK", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_nextK_pargs args;
+  args.scanner = &scanner;
+  args.k = &k;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_nextK(ScanResult& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("nextK") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_nextK_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "nextK failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::closeScanner(const std::string& scanner)
+{
+  int32_t seqid = send_closeScanner(scanner);
+  recv_closeScanner(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_closeScanner(const std::string& scanner)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("closeScanner", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_closeScanner_pargs args;
+  args.scanner = &scanner;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_closeScanner(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("closeScanner") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_closeScanner_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::updateAndFlush(const std::string& login, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
+{
+  int32_t seqid = send_updateAndFlush(login, tableName, cells);
+  recv_updateAndFlush(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_updateAndFlush(const std::string& login, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("updateAndFlush", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_updateAndFlush_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.cells = &cells;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_updateAndFlush(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("updateAndFlush") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_updateAndFlush_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.outch1) {
+        sentry.commit();
+        throw result.outch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      if (result.__isset.ouch4) {
+        sentry.commit();
+        throw result.ouch4;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::createWriter(std::string& _return, const std::string& login, const std::string& tableName, const WriterOptions& opts)
+{
+  int32_t seqid = send_createWriter(login, tableName, opts);
+  recv_createWriter(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_createWriter(const std::string& login, const std::string& tableName, const WriterOptions& opts)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("createWriter", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_createWriter_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.opts = &opts;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_createWriter(std::string& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("createWriter") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_createWriter_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.outch1) {
+        sentry.commit();
+        throw result.outch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createWriter failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
+{
+  send_update(writer, cells);
+}
+
+void AccumuloProxyConcurrentClient::send_update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells)
+{
+  int32_t cseqid = 0;
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("update", ::apache::thrift::protocol::T_ONEWAY, cseqid);
+
+  AccumuloProxy_update_pargs args;
+  args.writer = &writer;
+  args.cells = &cells;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+}
+
+void AccumuloProxyConcurrentClient::flush(const std::string& writer)
+{
+  int32_t seqid = send_flush(writer);
+  recv_flush(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_flush(const std::string& writer)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("flush", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_flush_pargs args;
+  args.writer = &writer;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_flush(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("flush") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_flush_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::closeWriter(const std::string& writer)
+{
+  int32_t seqid = send_closeWriter(writer);
+  recv_closeWriter(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_closeWriter(const std::string& writer)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("closeWriter", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_closeWriter_pargs args;
+  args.writer = &writer;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_closeWriter(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("closeWriter") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_closeWriter_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+ConditionalStatus::type AccumuloProxyConcurrentClient::updateRowConditionally(const std::string& login, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates)
+{
+  int32_t seqid = send_updateRowConditionally(login, tableName, row, updates);
+  return recv_updateRowConditionally(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_updateRowConditionally(const std::string& login, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("updateRowConditionally", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_updateRowConditionally_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.row = &row;
+  args.updates = &updates;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+ConditionalStatus::type AccumuloProxyConcurrentClient::recv_updateRowConditionally(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("updateRowConditionally") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      ConditionalStatus::type _return;
+      AccumuloProxy_updateRowConditionally_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "updateRowConditionally failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::createConditionalWriter(std::string& _return, const std::string& login, const std::string& tableName, const ConditionalWriterOptions& options)
+{
+  int32_t seqid = send_createConditionalWriter(login, tableName, options);
+  recv_createConditionalWriter(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_createConditionalWriter(const std::string& login, const std::string& tableName, const ConditionalWriterOptions& options)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("createConditionalWriter", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_createConditionalWriter_pargs args;
+  args.login = &login;
+  args.tableName = &tableName;
+  args.options = &options;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_createConditionalWriter(std::string& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("createConditionalWriter") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_createConditionalWriter_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "createConditionalWriter failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates)
+{
+  int32_t seqid = send_updateRowsConditionally(conditionalWriter, updates);
+  recv_updateRowsConditionally(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_updateRowsConditionally(const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("updateRowsConditionally", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_updateRowsConditionally_pargs args;
+  args.conditionalWriter = &conditionalWriter;
+  args.updates = &updates;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("updateRowsConditionally") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_updateRowsConditionally_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "updateRowsConditionally failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::closeConditionalWriter(const std::string& conditionalWriter)
+{
+  int32_t seqid = send_closeConditionalWriter(conditionalWriter);
+  recv_closeConditionalWriter(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_closeConditionalWriter(const std::string& conditionalWriter)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("closeConditionalWriter", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_closeConditionalWriter_pargs args;
+  args.conditionalWriter = &conditionalWriter;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_closeConditionalWriter(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("closeConditionalWriter") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_closeConditionalWriter_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getRowRange(Range& _return, const std::string& row)
+{
+  int32_t seqid = send_getRowRange(row);
+  recv_getRowRange(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getRowRange(const std::string& row)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getRowRange", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getRowRange_pargs args;
+  args.row = &row;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getRowRange(Range& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getRowRange") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getRowRange_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getRowRange failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getFollowing(Key& _return, const Key& key, const PartialKey::type part)
+{
+  int32_t seqid = send_getFollowing(key, part);
+  recv_getFollowing(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getFollowing(const Key& key, const PartialKey::type part)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getFollowing", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getFollowing_pargs args;
+  args.key = &key;
+  args.part = &part;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getFollowing(Key& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getFollowing") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getFollowing_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getFollowing failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::systemNamespace(std::string& _return)
+{
+  int32_t seqid = send_systemNamespace();
+  recv_systemNamespace(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_systemNamespace()
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("systemNamespace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_systemNamespace_pargs args;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_systemNamespace(std::string& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("systemNamespace") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_systemNamespace_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "systemNamespace failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::defaultNamespace(std::string& _return)
+{
+  int32_t seqid = send_defaultNamespace();
+  recv_defaultNamespace(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_defaultNamespace()
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("defaultNamespace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_defaultNamespace_pargs args;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_defaultNamespace(std::string& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("defaultNamespace") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_defaultNamespace_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "defaultNamespace failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::listNamespaces(std::vector<std::string> & _return, const std::string& login)
+{
+  int32_t seqid = send_listNamespaces(login);
+  recv_listNamespaces(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_listNamespaces(const std::string& login)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("listNamespaces", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listNamespaces_pargs args;
+  args.login = &login;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_listNamespaces(std::vector<std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("listNamespaces") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_listNamespaces_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaces failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+bool AccumuloProxyConcurrentClient::namespaceExists(const std::string& login, const std::string& namespaceName)
+{
+  int32_t seqid = send_namespaceExists(login, namespaceName);
+  return recv_namespaceExists(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_namespaceExists(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("namespaceExists", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_namespaceExists_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+bool AccumuloProxyConcurrentClient::recv_namespaceExists(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("namespaceExists") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      bool _return;
+      AccumuloProxy_namespaceExists_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "namespaceExists failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::createNamespace(const std::string& login, const std::string& namespaceName)
+{
+  int32_t seqid = send_createNamespace(login, namespaceName);
+  recv_createNamespace(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_createNamespace(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("createNamespace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_createNamespace_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_createNamespace(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("createNamespace") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_createNamespace_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::deleteNamespace(const std::string& login, const std::string& namespaceName)
+{
+  int32_t seqid = send_deleteNamespace(login, namespaceName);
+  recv_deleteNamespace(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_deleteNamespace(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("deleteNamespace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_deleteNamespace_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_deleteNamespace(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("deleteNamespace") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_deleteNamespace_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      if (result.__isset.ouch4) {
+        sentry.commit();
+        throw result.ouch4;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName)
+{
+  int32_t seqid = send_renameNamespace(login, oldNamespaceName, newNamespaceName);
+  recv_renameNamespace(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("renameNamespace", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_renameNamespace_pargs args;
+  args.login = &login;
+  args.oldNamespaceName = &oldNamespaceName;
+  args.newNamespaceName = &newNamespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_renameNamespace(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("renameNamespace") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_renameNamespace_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      if (result.__isset.ouch4) {
+        sentry.commit();
+        throw result.ouch4;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value)
+{
+  int32_t seqid = send_setNamespaceProperty(login, namespaceName, property, value);
+  recv_setNamespaceProperty(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("setNamespaceProperty", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_setNamespaceProperty_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.property = &property;
+  args.value = &value;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_setNamespaceProperty(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("setNamespaceProperty") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_setNamespaceProperty_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property)
+{
+  int32_t seqid = send_removeNamespaceProperty(login, namespaceName, property);
+  recv_removeNamespaceProperty(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("removeNamespaceProperty", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_removeNamespaceProperty_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.property = &property;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_removeNamespaceProperty(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("removeNamespaceProperty") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_removeNamespaceProperty_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName)
+{
+  int32_t seqid = send_getNamespaceProperties(login, namespaceName);
+  recv_getNamespaceProperties(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getNamespaceProperties(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getNamespaceProperties", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getNamespaceProperties_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getNamespaceProperties(std::map<std::string, std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getNamespaceProperties") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getNamespaceProperties_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getNamespaceProperties failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login)
+{
+  int32_t seqid = send_namespaceIdMap(login);
+  recv_namespaceIdMap(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_namespaceIdMap(const std::string& login)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("namespaceIdMap", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_namespaceIdMap_pargs args;
+  args.login = &login;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_namespaceIdMap(std::map<std::string, std::string> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("namespaceIdMap") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_namespaceIdMap_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "namespaceIdMap failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t seqid = send_attachNamespaceIterator(login, namespaceName, setting, scopes);
+  recv_attachNamespaceIterator(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("attachNamespaceIterator", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_attachNamespaceIterator_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.setting = &setting;
+  args.scopes = &scopes;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_attachNamespaceIterator(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("attachNamespaceIterator") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_attachNamespaceIterator_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t seqid = send_removeNamespaceIterator(login, namespaceName, name, scopes);
+  recv_removeNamespaceIterator(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("removeNamespaceIterator", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_removeNamespaceIterator_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.name = &name;
+  args.scopes = &scopes;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_removeNamespaceIterator(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("removeNamespaceIterator") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_removeNamespaceIterator_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope)
+{
+  int32_t seqid = send_getNamespaceIteratorSetting(login, namespaceName, name, scope);
+  recv_getNamespaceIteratorSetting(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_getNamespaceIteratorSetting(const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("getNamespaceIteratorSetting", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_getNamespaceIteratorSetting_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.name = &name;
+  args.scope = &scope;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_getNamespaceIteratorSetting(IteratorSetting& _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("getNamespaceIteratorSetting") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_getNamespaceIteratorSetting_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getNamespaceIteratorSetting failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName)
+{
+  int32_t seqid = send_listNamespaceIterators(login, namespaceName);
+  recv_listNamespaceIterators(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_listNamespaceIterators(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("listNamespaceIterators", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listNamespaceIterators_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("listNamespaceIterators") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_listNamespaceIterators_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaceIterators failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t seqid = send_checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes);
+  recv_checkNamespaceIteratorConflicts(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("checkNamespaceIteratorConflicts", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_checkNamespaceIteratorConflicts_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.setting = &setting;
+  args.scopes = &scopes;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_checkNamespaceIteratorConflicts(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("checkNamespaceIteratorConflicts") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_checkNamespaceIteratorConflicts_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+int32_t AccumuloProxyConcurrentClient::addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName)
+{
+  int32_t seqid = send_addNamespaceConstraint(login, namespaceName, constraintClassName);
+  return recv_addNamespaceConstraint(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("addNamespaceConstraint", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_addNamespaceConstraint_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.constraintClassName = &constraintClassName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+int32_t AccumuloProxyConcurrentClient::recv_addNamespaceConstraint(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("addNamespaceConstraint") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      int32_t _return;
+      AccumuloProxy_addNamespaceConstraint_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "addNamespaceConstraint failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id)
+{
+  int32_t seqid = send_removeNamespaceConstraint(login, namespaceName, id);
+  recv_removeNamespaceConstraint(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("removeNamespaceConstraint", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_removeNamespaceConstraint_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.id = &id;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_removeNamespaceConstraint(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("removeNamespaceConstraint") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_removeNamespaceConstraint_presult result;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      sentry.commit();
+      return;
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+void AccumuloProxyConcurrentClient::listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName)
+{
+  int32_t seqid = send_listNamespaceConstraints(login, namespaceName);
+  recv_listNamespaceConstraints(_return, seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_listNamespaceConstraints(const std::string& login, const std::string& namespaceName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("listNamespaceConstraints", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_listNamespaceConstraints_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+void AccumuloProxyConcurrentClient::recv_listNamespaceConstraints(std::map<std::string, int32_t> & _return, const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("listNamespaceConstraints") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      AccumuloProxy_listNamespaceConstraints_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        // _return pointer has now been filled
+        sentry.commit();
+        return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "listNamespaceConstraints failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
+bool AccumuloProxyConcurrentClient::testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName)
+{
+  int32_t seqid = send_testNamespaceClassLoad(login, namespaceName, className, asTypeName);
+  return recv_testNamespaceClassLoad(seqid);
+}
+
+int32_t AccumuloProxyConcurrentClient::send_testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName)
+{
+  int32_t cseqid = this->sync_.generateSeqId();
+  ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
+  oprot_->writeMessageBegin("testNamespaceClassLoad", ::apache::thrift::protocol::T_CALL, cseqid);
+
+  AccumuloProxy_testNamespaceClassLoad_pargs args;
+  args.login = &login;
+  args.namespaceName = &namespaceName;
+  args.className = &className;
+  args.asTypeName = &asTypeName;
+  args.write(oprot_);
+
+  oprot_->writeMessageEnd();
+  oprot_->getTransport()->writeEnd();
+  oprot_->getTransport()->flush();
+
+  sentry.commit();
+  return cseqid;
+}
+
+bool AccumuloProxyConcurrentClient::recv_testNamespaceClassLoad(const int32_t seqid)
+{
+
+  int32_t rseqid = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TMessageType mtype;
+
+  // the read mutex gets dropped and reacquired as part of waitForWork()
+  // The destructor of this sentry wakes up other clients
+  ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
+
+  while(true) {
+    if(!this->sync_.getPending(fname, mtype, rseqid)) {
+      iprot_->readMessageBegin(fname, mtype, rseqid);
+    }
+    if(seqid == rseqid) {
+      if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
+        ::apache::thrift::TApplicationException x;
+        x.read(iprot_);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+        sentry.commit();
+        throw x;
+      }
+      if (mtype != ::apache::thrift::protocol::T_REPLY) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+      }
+      if (fname.compare("testNamespaceClassLoad") != 0) {
+        iprot_->skip(::apache::thrift::protocol::T_STRUCT);
+        iprot_->readMessageEnd();
+        iprot_->getTransport()->readEnd();
+
+        // in a bad state, don't commit
+        using ::apache::thrift::protocol::TProtocolException;
+        throw TProtocolException(TProtocolException::INVALID_DATA);
+      }
+      bool _return;
+      AccumuloProxy_testNamespaceClassLoad_presult result;
+      result.success = &_return;
+      result.read(iprot_);
+      iprot_->readMessageEnd();
+      iprot_->getTransport()->readEnd();
+
+      if (result.__isset.success) {
+        sentry.commit();
+        return _return;
+      }
+      if (result.__isset.ouch1) {
+        sentry.commit();
+        throw result.ouch1;
+      }
+      if (result.__isset.ouch2) {
+        sentry.commit();
+        throw result.ouch2;
+      }
+      if (result.__isset.ouch3) {
+        sentry.commit();
+        throw result.ouch3;
+      }
+      // in a bad state, don't commit
+      throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "testNamespaceClassLoad failed: unknown result");
+    }
+    // seqid != rseqid
+    this->sync_.updatePending(fname, mtype, rseqid);
+
+    // this will temporarily unlock the readMutex, and let other clients get work done
+    this->sync_.waitForWork(seqid);
+  } // end while(true)
+}
+
 } // namespace
 
diff --git a/src/main/cpp/AccumuloProxy.h b/src/main/cpp/AccumuloProxy.h
index 269884f..429cf55 100644
--- a/src/main/cpp/AccumuloProxy.h
+++ b/src/main/cpp/AccumuloProxy.h
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -24,10 +24,16 @@
 #define AccumuloProxy_H
 
 #include <thrift/TDispatchProcessor.h>
+#include <thrift/async/TConcurrentClientSyncInfo.h>
 #include "proxy_types.h"
 
 namespace accumulo {
 
+#ifdef _WIN32
+  #pragma warning( push )
+  #pragma warning (disable : 4250 ) //inheriting methods via dominance 
+#endif
+
 class AccumuloProxyIf {
  public:
   virtual ~AccumuloProxyIf() {}
@@ -91,6 +97,9 @@
   virtual void listLocalUsers(std::set<std::string> & _return, const std::string& login) = 0;
   virtual void revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm) = 0;
   virtual void revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm) = 0;
+  virtual void grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) = 0;
+  virtual bool hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) = 0;
+  virtual void revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) = 0;
   virtual void createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options) = 0;
   virtual void createScanner(std::string& _return, const std::string& login, const std::string& tableName, const ScanOptions& options) = 0;
   virtual bool hasNext(const std::string& scanner) = 0;
@@ -108,6 +117,26 @@
   virtual void closeConditionalWriter(const std::string& conditionalWriter) = 0;
   virtual void getRowRange(Range& _return, const std::string& row) = 0;
   virtual void getFollowing(Key& _return, const Key& key, const PartialKey::type part) = 0;
+  virtual void systemNamespace(std::string& _return) = 0;
+  virtual void defaultNamespace(std::string& _return) = 0;
+  virtual void listNamespaces(std::vector<std::string> & _return, const std::string& login) = 0;
+  virtual bool namespaceExists(const std::string& login, const std::string& namespaceName) = 0;
+  virtual void createNamespace(const std::string& login, const std::string& namespaceName) = 0;
+  virtual void deleteNamespace(const std::string& login, const std::string& namespaceName) = 0;
+  virtual void renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName) = 0;
+  virtual void setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value) = 0;
+  virtual void removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property) = 0;
+  virtual void getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName) = 0;
+  virtual void namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login) = 0;
+  virtual void attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) = 0;
+  virtual void removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes) = 0;
+  virtual void getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope) = 0;
+  virtual void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName) = 0;
+  virtual void checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) = 0;
+  virtual int32_t addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName) = 0;
+  virtual void removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id) = 0;
+  virtual void listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName) = 0;
+  virtual bool testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName) = 0;
 };
 
 class AccumuloProxyIfFactory {
@@ -324,6 +353,16 @@
   void revokeTablePermission(const std::string& /* login */, const std::string& /* user */, const std::string& /* table */, const TablePermission::type /* perm */) {
     return;
   }
+  void grantNamespacePermission(const std::string& /* login */, const std::string& /* user */, const std::string& /* namespaceName */, const NamespacePermission::type /* perm */) {
+    return;
+  }
+  bool hasNamespacePermission(const std::string& /* login */, const std::string& /* user */, const std::string& /* namespaceName */, const NamespacePermission::type /* perm */) {
+    bool _return = false;
+    return _return;
+  }
+  void revokeNamespacePermission(const std::string& /* login */, const std::string& /* user */, const std::string& /* namespaceName */, const NamespacePermission::type /* perm */) {
+    return;
+  }
   void createBatchScanner(std::string& /* _return */, const std::string& /* login */, const std::string& /* tableName */, const BatchScanOptions& /* options */) {
     return;
   }
@@ -377,34 +416,94 @@
   void getFollowing(Key& /* _return */, const Key& /* key */, const PartialKey::type /* part */) {
     return;
   }
+  void systemNamespace(std::string& /* _return */) {
+    return;
+  }
+  void defaultNamespace(std::string& /* _return */) {
+    return;
+  }
+  void listNamespaces(std::vector<std::string> & /* _return */, const std::string& /* login */) {
+    return;
+  }
+  bool namespaceExists(const std::string& /* login */, const std::string& /* namespaceName */) {
+    bool _return = false;
+    return _return;
+  }
+  void createNamespace(const std::string& /* login */, const std::string& /* namespaceName */) {
+    return;
+  }
+  void deleteNamespace(const std::string& /* login */, const std::string& /* namespaceName */) {
+    return;
+  }
+  void renameNamespace(const std::string& /* login */, const std::string& /* oldNamespaceName */, const std::string& /* newNamespaceName */) {
+    return;
+  }
+  void setNamespaceProperty(const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* property */, const std::string& /* value */) {
+    return;
+  }
+  void removeNamespaceProperty(const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* property */) {
+    return;
+  }
+  void getNamespaceProperties(std::map<std::string, std::string> & /* _return */, const std::string& /* login */, const std::string& /* namespaceName */) {
+    return;
+  }
+  void namespaceIdMap(std::map<std::string, std::string> & /* _return */, const std::string& /* login */) {
+    return;
+  }
+  void attachNamespaceIterator(const std::string& /* login */, const std::string& /* namespaceName */, const IteratorSetting& /* setting */, const std::set<IteratorScope::type> & /* scopes */) {
+    return;
+  }
+  void removeNamespaceIterator(const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* name */, const std::set<IteratorScope::type> & /* scopes */) {
+    return;
+  }
+  void getNamespaceIteratorSetting(IteratorSetting& /* _return */, const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* name */, const IteratorScope::type /* scope */) {
+    return;
+  }
+  void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & /* _return */, const std::string& /* login */, const std::string& /* namespaceName */) {
+    return;
+  }
+  void checkNamespaceIteratorConflicts(const std::string& /* login */, const std::string& /* namespaceName */, const IteratorSetting& /* setting */, const std::set<IteratorScope::type> & /* scopes */) {
+    return;
+  }
+  int32_t addNamespaceConstraint(const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* constraintClassName */) {
+    int32_t _return = 0;
+    return _return;
+  }
+  void removeNamespaceConstraint(const std::string& /* login */, const std::string& /* namespaceName */, const int32_t /* id */) {
+    return;
+  }
+  void listNamespaceConstraints(std::map<std::string, int32_t> & /* _return */, const std::string& /* login */, const std::string& /* namespaceName */) {
+    return;
+  }
+  bool testNamespaceClassLoad(const std::string& /* login */, const std::string& /* namespaceName */, const std::string& /* className */, const std::string& /* asTypeName */) {
+    bool _return = false;
+    return _return;
+  }
 };
 
 typedef struct _AccumuloProxy_login_args__isset {
   _AccumuloProxy_login_args__isset() : principal(false), loginProperties(false) {}
-  bool principal;
-  bool loginProperties;
+  bool principal :1;
+  bool loginProperties :1;
 } _AccumuloProxy_login_args__isset;
 
 class AccumuloProxy_login_args {
  public:
 
+  AccumuloProxy_login_args(const AccumuloProxy_login_args&);
+  AccumuloProxy_login_args& operator=(const AccumuloProxy_login_args&);
   AccumuloProxy_login_args() : principal() {
   }
 
-  virtual ~AccumuloProxy_login_args() throw() {}
-
+  virtual ~AccumuloProxy_login_args() throw();
   std::string principal;
   std::map<std::string, std::string>  loginProperties;
 
   _AccumuloProxy_login_args__isset __isset;
 
-  void __set_principal(const std::string& val) {
-    principal = val;
-  }
+  void __set_principal(const std::string& val);
 
-  void __set_loginProperties(const std::map<std::string, std::string> & val) {
-    loginProperties = val;
-  }
+  void __set_loginProperties(const std::map<std::string, std::string> & val);
 
   bool operator == (const AccumuloProxy_login_args & rhs) const
   {
@@ -430,8 +529,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_login_pargs() throw() {}
-
+  virtual ~AccumuloProxy_login_pargs() throw();
   const std::string* principal;
   const std::map<std::string, std::string> * loginProperties;
 
@@ -441,30 +539,27 @@
 
 typedef struct _AccumuloProxy_login_result__isset {
   _AccumuloProxy_login_result__isset() : success(false), ouch2(false) {}
-  bool success;
-  bool ouch2;
+  bool success :1;
+  bool ouch2 :1;
 } _AccumuloProxy_login_result__isset;
 
 class AccumuloProxy_login_result {
  public:
 
+  AccumuloProxy_login_result(const AccumuloProxy_login_result&);
+  AccumuloProxy_login_result& operator=(const AccumuloProxy_login_result&);
   AccumuloProxy_login_result() : success() {
   }
 
-  virtual ~AccumuloProxy_login_result() throw() {}
-
+  virtual ~AccumuloProxy_login_result() throw();
   std::string success;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_login_result__isset __isset;
 
-  void __set_success(const std::string& val) {
-    success = val;
-  }
+  void __set_success(const std::string& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_login_result & rhs) const
   {
@@ -487,16 +582,15 @@
 
 typedef struct _AccumuloProxy_login_presult__isset {
   _AccumuloProxy_login_presult__isset() : success(false), ouch2(false) {}
-  bool success;
-  bool ouch2;
+  bool success :1;
+  bool ouch2 :1;
 } _AccumuloProxy_login_presult__isset;
 
 class AccumuloProxy_login_presult {
  public:
 
 
-  virtual ~AccumuloProxy_login_presult() throw() {}
-
+  virtual ~AccumuloProxy_login_presult() throw();
   std::string* success;
   AccumuloSecurityException ouch2;
 
@@ -508,36 +602,31 @@
 
 typedef struct _AccumuloProxy_addConstraint_args__isset {
   _AccumuloProxy_addConstraint_args__isset() : login(false), tableName(false), constraintClassName(false) {}
-  bool login;
-  bool tableName;
-  bool constraintClassName;
+  bool login :1;
+  bool tableName :1;
+  bool constraintClassName :1;
 } _AccumuloProxy_addConstraint_args__isset;
 
 class AccumuloProxy_addConstraint_args {
  public:
 
+  AccumuloProxy_addConstraint_args(const AccumuloProxy_addConstraint_args&);
+  AccumuloProxy_addConstraint_args& operator=(const AccumuloProxy_addConstraint_args&);
   AccumuloProxy_addConstraint_args() : login(), tableName(), constraintClassName() {
   }
 
-  virtual ~AccumuloProxy_addConstraint_args() throw() {}
-
+  virtual ~AccumuloProxy_addConstraint_args() throw();
   std::string login;
   std::string tableName;
   std::string constraintClassName;
 
   _AccumuloProxy_addConstraint_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_constraintClassName(const std::string& val) {
-    constraintClassName = val;
-  }
+  void __set_constraintClassName(const std::string& val);
 
   bool operator == (const AccumuloProxy_addConstraint_args & rhs) const
   {
@@ -565,8 +654,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_addConstraint_pargs() throw() {}
-
+  virtual ~AccumuloProxy_addConstraint_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* constraintClassName;
@@ -577,20 +665,21 @@
 
 typedef struct _AccumuloProxy_addConstraint_result__isset {
   _AccumuloProxy_addConstraint_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_addConstraint_result__isset;
 
 class AccumuloProxy_addConstraint_result {
  public:
 
+  AccumuloProxy_addConstraint_result(const AccumuloProxy_addConstraint_result&);
+  AccumuloProxy_addConstraint_result& operator=(const AccumuloProxy_addConstraint_result&);
   AccumuloProxy_addConstraint_result() : success(0) {
   }
 
-  virtual ~AccumuloProxy_addConstraint_result() throw() {}
-
+  virtual ~AccumuloProxy_addConstraint_result() throw();
   int32_t success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -598,21 +687,13 @@
 
   _AccumuloProxy_addConstraint_result__isset __isset;
 
-  void __set_success(const int32_t val) {
-    success = val;
-  }
+  void __set_success(const int32_t val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_addConstraint_result & rhs) const
   {
@@ -639,18 +720,17 @@
 
 typedef struct _AccumuloProxy_addConstraint_presult__isset {
   _AccumuloProxy_addConstraint_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_addConstraint_presult__isset;
 
 class AccumuloProxy_addConstraint_presult {
  public:
 
 
-  virtual ~AccumuloProxy_addConstraint_presult() throw() {}
-
+  virtual ~AccumuloProxy_addConstraint_presult() throw();
   int32_t* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -664,36 +744,31 @@
 
 typedef struct _AccumuloProxy_addSplits_args__isset {
   _AccumuloProxy_addSplits_args__isset() : login(false), tableName(false), splits(false) {}
-  bool login;
-  bool tableName;
-  bool splits;
+  bool login :1;
+  bool tableName :1;
+  bool splits :1;
 } _AccumuloProxy_addSplits_args__isset;
 
 class AccumuloProxy_addSplits_args {
  public:
 
+  AccumuloProxy_addSplits_args(const AccumuloProxy_addSplits_args&);
+  AccumuloProxy_addSplits_args& operator=(const AccumuloProxy_addSplits_args&);
   AccumuloProxy_addSplits_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_addSplits_args() throw() {}
-
+  virtual ~AccumuloProxy_addSplits_args() throw();
   std::string login;
   std::string tableName;
   std::set<std::string>  splits;
 
   _AccumuloProxy_addSplits_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_splits(const std::set<std::string> & val) {
-    splits = val;
-  }
+  void __set_splits(const std::set<std::string> & val);
 
   bool operator == (const AccumuloProxy_addSplits_args & rhs) const
   {
@@ -721,8 +796,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_addSplits_pargs() throw() {}
-
+  virtual ~AccumuloProxy_addSplits_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::set<std::string> * splits;
@@ -733,36 +807,31 @@
 
 typedef struct _AccumuloProxy_addSplits_result__isset {
   _AccumuloProxy_addSplits_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_addSplits_result__isset;
 
 class AccumuloProxy_addSplits_result {
  public:
 
+  AccumuloProxy_addSplits_result(const AccumuloProxy_addSplits_result&);
+  AccumuloProxy_addSplits_result& operator=(const AccumuloProxy_addSplits_result&);
   AccumuloProxy_addSplits_result() {
   }
 
-  virtual ~AccumuloProxy_addSplits_result() throw() {}
-
+  virtual ~AccumuloProxy_addSplits_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_addSplits_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_addSplits_result & rhs) const
   {
@@ -787,17 +856,16 @@
 
 typedef struct _AccumuloProxy_addSplits_presult__isset {
   _AccumuloProxy_addSplits_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_addSplits_presult__isset;
 
 class AccumuloProxy_addSplits_presult {
  public:
 
 
-  virtual ~AccumuloProxy_addSplits_presult() throw() {}
-
+  virtual ~AccumuloProxy_addSplits_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -810,20 +878,21 @@
 
 typedef struct _AccumuloProxy_attachIterator_args__isset {
   _AccumuloProxy_attachIterator_args__isset() : login(false), tableName(false), setting(false), scopes(false) {}
-  bool login;
-  bool tableName;
-  bool setting;
-  bool scopes;
+  bool login :1;
+  bool tableName :1;
+  bool setting :1;
+  bool scopes :1;
 } _AccumuloProxy_attachIterator_args__isset;
 
 class AccumuloProxy_attachIterator_args {
  public:
 
+  AccumuloProxy_attachIterator_args(const AccumuloProxy_attachIterator_args&);
+  AccumuloProxy_attachIterator_args& operator=(const AccumuloProxy_attachIterator_args&);
   AccumuloProxy_attachIterator_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_attachIterator_args() throw() {}
-
+  virtual ~AccumuloProxy_attachIterator_args() throw();
   std::string login;
   std::string tableName;
   IteratorSetting setting;
@@ -831,21 +900,13 @@
 
   _AccumuloProxy_attachIterator_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_setting(const IteratorSetting& val) {
-    setting = val;
-  }
+  void __set_setting(const IteratorSetting& val);
 
-  void __set_scopes(const std::set<IteratorScope::type> & val) {
-    scopes = val;
-  }
+  void __set_scopes(const std::set<IteratorScope::type> & val);
 
   bool operator == (const AccumuloProxy_attachIterator_args & rhs) const
   {
@@ -875,8 +936,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_attachIterator_pargs() throw() {}
-
+  virtual ~AccumuloProxy_attachIterator_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const IteratorSetting* setting;
@@ -888,36 +948,31 @@
 
 typedef struct _AccumuloProxy_attachIterator_result__isset {
   _AccumuloProxy_attachIterator_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_attachIterator_result__isset;
 
 class AccumuloProxy_attachIterator_result {
  public:
 
+  AccumuloProxy_attachIterator_result(const AccumuloProxy_attachIterator_result&);
+  AccumuloProxy_attachIterator_result& operator=(const AccumuloProxy_attachIterator_result&);
   AccumuloProxy_attachIterator_result() {
   }
 
-  virtual ~AccumuloProxy_attachIterator_result() throw() {}
-
+  virtual ~AccumuloProxy_attachIterator_result() throw();
   AccumuloSecurityException ouch1;
   AccumuloException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_attachIterator_result__isset __isset;
 
-  void __set_ouch1(const AccumuloSecurityException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloSecurityException& val);
 
-  void __set_ouch2(const AccumuloException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_attachIterator_result & rhs) const
   {
@@ -942,17 +997,16 @@
 
 typedef struct _AccumuloProxy_attachIterator_presult__isset {
   _AccumuloProxy_attachIterator_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_attachIterator_presult__isset;
 
 class AccumuloProxy_attachIterator_presult {
  public:
 
 
-  virtual ~AccumuloProxy_attachIterator_presult() throw() {}
-
+  virtual ~AccumuloProxy_attachIterator_presult() throw();
   AccumuloSecurityException ouch1;
   AccumuloException ouch2;
   TableNotFoundException ouch3;
@@ -965,20 +1019,21 @@
 
 typedef struct _AccumuloProxy_checkIteratorConflicts_args__isset {
   _AccumuloProxy_checkIteratorConflicts_args__isset() : login(false), tableName(false), setting(false), scopes(false) {}
-  bool login;
-  bool tableName;
-  bool setting;
-  bool scopes;
+  bool login :1;
+  bool tableName :1;
+  bool setting :1;
+  bool scopes :1;
 } _AccumuloProxy_checkIteratorConflicts_args__isset;
 
 class AccumuloProxy_checkIteratorConflicts_args {
  public:
 
+  AccumuloProxy_checkIteratorConflicts_args(const AccumuloProxy_checkIteratorConflicts_args&);
+  AccumuloProxy_checkIteratorConflicts_args& operator=(const AccumuloProxy_checkIteratorConflicts_args&);
   AccumuloProxy_checkIteratorConflicts_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_checkIteratorConflicts_args() throw() {}
-
+  virtual ~AccumuloProxy_checkIteratorConflicts_args() throw();
   std::string login;
   std::string tableName;
   IteratorSetting setting;
@@ -986,21 +1041,13 @@
 
   _AccumuloProxy_checkIteratorConflicts_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_setting(const IteratorSetting& val) {
-    setting = val;
-  }
+  void __set_setting(const IteratorSetting& val);
 
-  void __set_scopes(const std::set<IteratorScope::type> & val) {
-    scopes = val;
-  }
+  void __set_scopes(const std::set<IteratorScope::type> & val);
 
   bool operator == (const AccumuloProxy_checkIteratorConflicts_args & rhs) const
   {
@@ -1030,8 +1077,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_checkIteratorConflicts_pargs() throw() {}
-
+  virtual ~AccumuloProxy_checkIteratorConflicts_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const IteratorSetting* setting;
@@ -1043,36 +1089,31 @@
 
 typedef struct _AccumuloProxy_checkIteratorConflicts_result__isset {
   _AccumuloProxy_checkIteratorConflicts_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_checkIteratorConflicts_result__isset;
 
 class AccumuloProxy_checkIteratorConflicts_result {
  public:
 
+  AccumuloProxy_checkIteratorConflicts_result(const AccumuloProxy_checkIteratorConflicts_result&);
+  AccumuloProxy_checkIteratorConflicts_result& operator=(const AccumuloProxy_checkIteratorConflicts_result&);
   AccumuloProxy_checkIteratorConflicts_result() {
   }
 
-  virtual ~AccumuloProxy_checkIteratorConflicts_result() throw() {}
-
+  virtual ~AccumuloProxy_checkIteratorConflicts_result() throw();
   AccumuloSecurityException ouch1;
   AccumuloException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_checkIteratorConflicts_result__isset __isset;
 
-  void __set_ouch1(const AccumuloSecurityException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloSecurityException& val);
 
-  void __set_ouch2(const AccumuloException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_checkIteratorConflicts_result & rhs) const
   {
@@ -1097,17 +1138,16 @@
 
 typedef struct _AccumuloProxy_checkIteratorConflicts_presult__isset {
   _AccumuloProxy_checkIteratorConflicts_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_checkIteratorConflicts_presult__isset;
 
 class AccumuloProxy_checkIteratorConflicts_presult {
  public:
 
 
-  virtual ~AccumuloProxy_checkIteratorConflicts_presult() throw() {}
-
+  virtual ~AccumuloProxy_checkIteratorConflicts_presult() throw();
   AccumuloSecurityException ouch1;
   AccumuloException ouch2;
   TableNotFoundException ouch3;
@@ -1120,30 +1160,27 @@
 
 typedef struct _AccumuloProxy_clearLocatorCache_args__isset {
   _AccumuloProxy_clearLocatorCache_args__isset() : login(false), tableName(false) {}
-  bool login;
-  bool tableName;
+  bool login :1;
+  bool tableName :1;
 } _AccumuloProxy_clearLocatorCache_args__isset;
 
 class AccumuloProxy_clearLocatorCache_args {
  public:
 
+  AccumuloProxy_clearLocatorCache_args(const AccumuloProxy_clearLocatorCache_args&);
+  AccumuloProxy_clearLocatorCache_args& operator=(const AccumuloProxy_clearLocatorCache_args&);
   AccumuloProxy_clearLocatorCache_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_clearLocatorCache_args() throw() {}
-
+  virtual ~AccumuloProxy_clearLocatorCache_args() throw();
   std::string login;
   std::string tableName;
 
   _AccumuloProxy_clearLocatorCache_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
   bool operator == (const AccumuloProxy_clearLocatorCache_args & rhs) const
   {
@@ -1169,8 +1206,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_clearLocatorCache_pargs() throw() {}
-
+  virtual ~AccumuloProxy_clearLocatorCache_pargs() throw();
   const std::string* login;
   const std::string* tableName;
 
@@ -1180,24 +1216,23 @@
 
 typedef struct _AccumuloProxy_clearLocatorCache_result__isset {
   _AccumuloProxy_clearLocatorCache_result__isset() : ouch1(false) {}
-  bool ouch1;
+  bool ouch1 :1;
 } _AccumuloProxy_clearLocatorCache_result__isset;
 
 class AccumuloProxy_clearLocatorCache_result {
  public:
 
+  AccumuloProxy_clearLocatorCache_result(const AccumuloProxy_clearLocatorCache_result&);
+  AccumuloProxy_clearLocatorCache_result& operator=(const AccumuloProxy_clearLocatorCache_result&);
   AccumuloProxy_clearLocatorCache_result() {
   }
 
-  virtual ~AccumuloProxy_clearLocatorCache_result() throw() {}
-
+  virtual ~AccumuloProxy_clearLocatorCache_result() throw();
   TableNotFoundException ouch1;
 
   _AccumuloProxy_clearLocatorCache_result__isset __isset;
 
-  void __set_ouch1(const TableNotFoundException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_clearLocatorCache_result & rhs) const
   {
@@ -1218,15 +1253,14 @@
 
 typedef struct _AccumuloProxy_clearLocatorCache_presult__isset {
   _AccumuloProxy_clearLocatorCache_presult__isset() : ouch1(false) {}
-  bool ouch1;
+  bool ouch1 :1;
 } _AccumuloProxy_clearLocatorCache_presult__isset;
 
 class AccumuloProxy_clearLocatorCache_presult {
  public:
 
 
-  virtual ~AccumuloProxy_clearLocatorCache_presult() throw() {}
-
+  virtual ~AccumuloProxy_clearLocatorCache_presult() throw();
   TableNotFoundException ouch1;
 
   _AccumuloProxy_clearLocatorCache_presult__isset __isset;
@@ -1237,22 +1271,23 @@
 
 typedef struct _AccumuloProxy_cloneTable_args__isset {
   _AccumuloProxy_cloneTable_args__isset() : login(false), tableName(false), newTableName(false), flush(false), propertiesToSet(false), propertiesToExclude(false) {}
-  bool login;
-  bool tableName;
-  bool newTableName;
-  bool flush;
-  bool propertiesToSet;
-  bool propertiesToExclude;
+  bool login :1;
+  bool tableName :1;
+  bool newTableName :1;
+  bool flush :1;
+  bool propertiesToSet :1;
+  bool propertiesToExclude :1;
 } _AccumuloProxy_cloneTable_args__isset;
 
 class AccumuloProxy_cloneTable_args {
  public:
 
+  AccumuloProxy_cloneTable_args(const AccumuloProxy_cloneTable_args&);
+  AccumuloProxy_cloneTable_args& operator=(const AccumuloProxy_cloneTable_args&);
   AccumuloProxy_cloneTable_args() : login(), tableName(), newTableName(), flush(0) {
   }
 
-  virtual ~AccumuloProxy_cloneTable_args() throw() {}
-
+  virtual ~AccumuloProxy_cloneTable_args() throw();
   std::string login;
   std::string tableName;
   std::string newTableName;
@@ -1262,29 +1297,17 @@
 
   _AccumuloProxy_cloneTable_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_newTableName(const std::string& val) {
-    newTableName = val;
-  }
+  void __set_newTableName(const std::string& val);
 
-  void __set_flush(const bool val) {
-    flush = val;
-  }
+  void __set_flush(const bool val);
 
-  void __set_propertiesToSet(const std::map<std::string, std::string> & val) {
-    propertiesToSet = val;
-  }
+  void __set_propertiesToSet(const std::map<std::string, std::string> & val);
 
-  void __set_propertiesToExclude(const std::set<std::string> & val) {
-    propertiesToExclude = val;
-  }
+  void __set_propertiesToExclude(const std::set<std::string> & val);
 
   bool operator == (const AccumuloProxy_cloneTable_args & rhs) const
   {
@@ -1318,8 +1341,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_cloneTable_pargs() throw() {}
-
+  virtual ~AccumuloProxy_cloneTable_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* newTableName;
@@ -1333,20 +1355,21 @@
 
 typedef struct _AccumuloProxy_cloneTable_result__isset {
   _AccumuloProxy_cloneTable_result__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
-  bool ouch4;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
 } _AccumuloProxy_cloneTable_result__isset;
 
 class AccumuloProxy_cloneTable_result {
  public:
 
+  AccumuloProxy_cloneTable_result(const AccumuloProxy_cloneTable_result&);
+  AccumuloProxy_cloneTable_result& operator=(const AccumuloProxy_cloneTable_result&);
   AccumuloProxy_cloneTable_result() {
   }
 
-  virtual ~AccumuloProxy_cloneTable_result() throw() {}
-
+  virtual ~AccumuloProxy_cloneTable_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -1354,21 +1377,13 @@
 
   _AccumuloProxy_cloneTable_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
-  void __set_ouch4(const TableExistsException& val) {
-    ouch4 = val;
-  }
+  void __set_ouch4(const TableExistsException& val);
 
   bool operator == (const AccumuloProxy_cloneTable_result & rhs) const
   {
@@ -1395,18 +1410,17 @@
 
 typedef struct _AccumuloProxy_cloneTable_presult__isset {
   _AccumuloProxy_cloneTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
-  bool ouch4;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
 } _AccumuloProxy_cloneTable_presult__isset;
 
 class AccumuloProxy_cloneTable_presult {
  public:
 
 
-  virtual ~AccumuloProxy_cloneTable_presult() throw() {}
-
+  virtual ~AccumuloProxy_cloneTable_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -1420,24 +1434,25 @@
 
 typedef struct _AccumuloProxy_compactTable_args__isset {
   _AccumuloProxy_compactTable_args__isset() : login(false), tableName(false), startRow(false), endRow(false), iterators(false), flush(false), wait(false), compactionStrategy(false) {}
-  bool login;
-  bool tableName;
-  bool startRow;
-  bool endRow;
-  bool iterators;
-  bool flush;
-  bool wait;
-  bool compactionStrategy;
+  bool login :1;
+  bool tableName :1;
+  bool startRow :1;
+  bool endRow :1;
+  bool iterators :1;
+  bool flush :1;
+  bool wait :1;
+  bool compactionStrategy :1;
 } _AccumuloProxy_compactTable_args__isset;
 
 class AccumuloProxy_compactTable_args {
  public:
 
+  AccumuloProxy_compactTable_args(const AccumuloProxy_compactTable_args&);
+  AccumuloProxy_compactTable_args& operator=(const AccumuloProxy_compactTable_args&);
   AccumuloProxy_compactTable_args() : login(), tableName(), startRow(), endRow(), flush(0), wait(0) {
   }
 
-  virtual ~AccumuloProxy_compactTable_args() throw() {}
-
+  virtual ~AccumuloProxy_compactTable_args() throw();
   std::string login;
   std::string tableName;
   std::string startRow;
@@ -1449,37 +1464,21 @@
 
   _AccumuloProxy_compactTable_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_startRow(const std::string& val) {
-    startRow = val;
-  }
+  void __set_startRow(const std::string& val);
 
-  void __set_endRow(const std::string& val) {
-    endRow = val;
-  }
+  void __set_endRow(const std::string& val);
 
-  void __set_iterators(const std::vector<IteratorSetting> & val) {
-    iterators = val;
-  }
+  void __set_iterators(const std::vector<IteratorSetting> & val);
 
-  void __set_flush(const bool val) {
-    flush = val;
-  }
+  void __set_flush(const bool val);
 
-  void __set_wait(const bool val) {
-    wait = val;
-  }
+  void __set_wait(const bool val);
 
-  void __set_compactionStrategy(const CompactionStrategyConfig& val) {
-    compactionStrategy = val;
-  }
+  void __set_compactionStrategy(const CompactionStrategyConfig& val);
 
   bool operator == (const AccumuloProxy_compactTable_args & rhs) const
   {
@@ -1517,8 +1516,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_compactTable_pargs() throw() {}
-
+  virtual ~AccumuloProxy_compactTable_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* startRow;
@@ -1534,36 +1532,31 @@
 
 typedef struct _AccumuloProxy_compactTable_result__isset {
   _AccumuloProxy_compactTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_compactTable_result__isset;
 
 class AccumuloProxy_compactTable_result {
  public:
 
+  AccumuloProxy_compactTable_result(const AccumuloProxy_compactTable_result&);
+  AccumuloProxy_compactTable_result& operator=(const AccumuloProxy_compactTable_result&);
   AccumuloProxy_compactTable_result() {
   }
 
-  virtual ~AccumuloProxy_compactTable_result() throw() {}
-
+  virtual ~AccumuloProxy_compactTable_result() throw();
   AccumuloSecurityException ouch1;
   TableNotFoundException ouch2;
   AccumuloException ouch3;
 
   _AccumuloProxy_compactTable_result__isset __isset;
 
-  void __set_ouch1(const AccumuloSecurityException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloSecurityException& val);
 
-  void __set_ouch2(const TableNotFoundException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const TableNotFoundException& val);
 
-  void __set_ouch3(const AccumuloException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const AccumuloException& val);
 
   bool operator == (const AccumuloProxy_compactTable_result & rhs) const
   {
@@ -1588,17 +1581,16 @@
 
 typedef struct _AccumuloProxy_compactTable_presult__isset {
   _AccumuloProxy_compactTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_compactTable_presult__isset;
 
 class AccumuloProxy_compactTable_presult {
  public:
 
 
-  virtual ~AccumuloProxy_compactTable_presult() throw() {}
-
+  virtual ~AccumuloProxy_compactTable_presult() throw();
   AccumuloSecurityException ouch1;
   TableNotFoundException ouch2;
   AccumuloException ouch3;
@@ -1611,30 +1603,27 @@
 
 typedef struct _AccumuloProxy_cancelCompaction_args__isset {
   _AccumuloProxy_cancelCompaction_args__isset() : login(false), tableName(false) {}
-  bool login;
-  bool tableName;
+  bool login :1;
+  bool tableName :1;
 } _AccumuloProxy_cancelCompaction_args__isset;
 
 class AccumuloProxy_cancelCompaction_args {
  public:
 
+  AccumuloProxy_cancelCompaction_args(const AccumuloProxy_cancelCompaction_args&);
+  AccumuloProxy_cancelCompaction_args& operator=(const AccumuloProxy_cancelCompaction_args&);
   AccumuloProxy_cancelCompaction_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_cancelCompaction_args() throw() {}
-
+  virtual ~AccumuloProxy_cancelCompaction_args() throw();
   std::string login;
   std::string tableName;
 
   _AccumuloProxy_cancelCompaction_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
   bool operator == (const AccumuloProxy_cancelCompaction_args & rhs) const
   {
@@ -1660,8 +1649,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_cancelCompaction_pargs() throw() {}
-
+  virtual ~AccumuloProxy_cancelCompaction_pargs() throw();
   const std::string* login;
   const std::string* tableName;
 
@@ -1671,36 +1659,31 @@
 
 typedef struct _AccumuloProxy_cancelCompaction_result__isset {
   _AccumuloProxy_cancelCompaction_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_cancelCompaction_result__isset;
 
 class AccumuloProxy_cancelCompaction_result {
  public:
 
+  AccumuloProxy_cancelCompaction_result(const AccumuloProxy_cancelCompaction_result&);
+  AccumuloProxy_cancelCompaction_result& operator=(const AccumuloProxy_cancelCompaction_result&);
   AccumuloProxy_cancelCompaction_result() {
   }
 
-  virtual ~AccumuloProxy_cancelCompaction_result() throw() {}
-
+  virtual ~AccumuloProxy_cancelCompaction_result() throw();
   AccumuloSecurityException ouch1;
   TableNotFoundException ouch2;
   AccumuloException ouch3;
 
   _AccumuloProxy_cancelCompaction_result__isset __isset;
 
-  void __set_ouch1(const AccumuloSecurityException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloSecurityException& val);
 
-  void __set_ouch2(const TableNotFoundException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const TableNotFoundException& val);
 
-  void __set_ouch3(const AccumuloException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const AccumuloException& val);
 
   bool operator == (const AccumuloProxy_cancelCompaction_result & rhs) const
   {
@@ -1725,17 +1708,16 @@
 
 typedef struct _AccumuloProxy_cancelCompaction_presult__isset {
   _AccumuloProxy_cancelCompaction_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_cancelCompaction_presult__isset;
 
 class AccumuloProxy_cancelCompaction_presult {
  public:
 
 
-  virtual ~AccumuloProxy_cancelCompaction_presult() throw() {}
-
+  virtual ~AccumuloProxy_cancelCompaction_presult() throw();
   AccumuloSecurityException ouch1;
   TableNotFoundException ouch2;
   AccumuloException ouch3;
@@ -1748,20 +1730,21 @@
 
 typedef struct _AccumuloProxy_createTable_args__isset {
   _AccumuloProxy_createTable_args__isset() : login(false), tableName(false), versioningIter(false), type(false) {}
-  bool login;
-  bool tableName;
-  bool versioningIter;
-  bool type;
+  bool login :1;
+  bool tableName :1;
+  bool versioningIter :1;
+  bool type :1;
 } _AccumuloProxy_createTable_args__isset;
 
 class AccumuloProxy_createTable_args {
  public:
 
+  AccumuloProxy_createTable_args(const AccumuloProxy_createTable_args&);
+  AccumuloProxy_createTable_args& operator=(const AccumuloProxy_createTable_args&);
   AccumuloProxy_createTable_args() : login(), tableName(), versioningIter(0), type((TimeType::type)0) {
   }
 
-  virtual ~AccumuloProxy_createTable_args() throw() {}
-
+  virtual ~AccumuloProxy_createTable_args() throw();
   std::string login;
   std::string tableName;
   bool versioningIter;
@@ -1769,21 +1752,13 @@
 
   _AccumuloProxy_createTable_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_versioningIter(const bool val) {
-    versioningIter = val;
-  }
+  void __set_versioningIter(const bool val);
 
-  void __set_type(const TimeType::type val) {
-    type = val;
-  }
+  void __set_type(const TimeType::type val);
 
   bool operator == (const AccumuloProxy_createTable_args & rhs) const
   {
@@ -1813,8 +1788,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_createTable_pargs() throw() {}
-
+  virtual ~AccumuloProxy_createTable_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const bool* versioningIter;
@@ -1826,36 +1800,31 @@
 
 typedef struct _AccumuloProxy_createTable_result__isset {
   _AccumuloProxy_createTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_createTable_result__isset;
 
 class AccumuloProxy_createTable_result {
  public:
 
+  AccumuloProxy_createTable_result(const AccumuloProxy_createTable_result&);
+  AccumuloProxy_createTable_result& operator=(const AccumuloProxy_createTable_result&);
   AccumuloProxy_createTable_result() {
   }
 
-  virtual ~AccumuloProxy_createTable_result() throw() {}
-
+  virtual ~AccumuloProxy_createTable_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableExistsException ouch3;
 
   _AccumuloProxy_createTable_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableExistsException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableExistsException& val);
 
   bool operator == (const AccumuloProxy_createTable_result & rhs) const
   {
@@ -1880,17 +1849,16 @@
 
 typedef struct _AccumuloProxy_createTable_presult__isset {
   _AccumuloProxy_createTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_createTable_presult__isset;
 
 class AccumuloProxy_createTable_presult {
  public:
 
 
-  virtual ~AccumuloProxy_createTable_presult() throw() {}
-
+  virtual ~AccumuloProxy_createTable_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableExistsException ouch3;
@@ -1903,30 +1871,27 @@
 
 typedef struct _AccumuloProxy_deleteTable_args__isset {
   _AccumuloProxy_deleteTable_args__isset() : login(false), tableName(false) {}
-  bool login;
-  bool tableName;
+  bool login :1;
+  bool tableName :1;
 } _AccumuloProxy_deleteTable_args__isset;
 
 class AccumuloProxy_deleteTable_args {
  public:
 
+  AccumuloProxy_deleteTable_args(const AccumuloProxy_deleteTable_args&);
+  AccumuloProxy_deleteTable_args& operator=(const AccumuloProxy_deleteTable_args&);
   AccumuloProxy_deleteTable_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_deleteTable_args() throw() {}
-
+  virtual ~AccumuloProxy_deleteTable_args() throw();
   std::string login;
   std::string tableName;
 
   _AccumuloProxy_deleteTable_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
   bool operator == (const AccumuloProxy_deleteTable_args & rhs) const
   {
@@ -1952,8 +1917,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_deleteTable_pargs() throw() {}
-
+  virtual ~AccumuloProxy_deleteTable_pargs() throw();
   const std::string* login;
   const std::string* tableName;
 
@@ -1963,36 +1927,31 @@
 
 typedef struct _AccumuloProxy_deleteTable_result__isset {
   _AccumuloProxy_deleteTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_deleteTable_result__isset;
 
 class AccumuloProxy_deleteTable_result {
  public:
 
+  AccumuloProxy_deleteTable_result(const AccumuloProxy_deleteTable_result&);
+  AccumuloProxy_deleteTable_result& operator=(const AccumuloProxy_deleteTable_result&);
   AccumuloProxy_deleteTable_result() {
   }
 
-  virtual ~AccumuloProxy_deleteTable_result() throw() {}
-
+  virtual ~AccumuloProxy_deleteTable_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_deleteTable_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_deleteTable_result & rhs) const
   {
@@ -2017,17 +1976,16 @@
 
 typedef struct _AccumuloProxy_deleteTable_presult__isset {
   _AccumuloProxy_deleteTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_deleteTable_presult__isset;
 
 class AccumuloProxy_deleteTable_presult {
  public:
 
 
-  virtual ~AccumuloProxy_deleteTable_presult() throw() {}
-
+  virtual ~AccumuloProxy_deleteTable_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -2040,20 +1998,21 @@
 
 typedef struct _AccumuloProxy_deleteRows_args__isset {
   _AccumuloProxy_deleteRows_args__isset() : login(false), tableName(false), startRow(false), endRow(false) {}
-  bool login;
-  bool tableName;
-  bool startRow;
-  bool endRow;
+  bool login :1;
+  bool tableName :1;
+  bool startRow :1;
+  bool endRow :1;
 } _AccumuloProxy_deleteRows_args__isset;
 
 class AccumuloProxy_deleteRows_args {
  public:
 
+  AccumuloProxy_deleteRows_args(const AccumuloProxy_deleteRows_args&);
+  AccumuloProxy_deleteRows_args& operator=(const AccumuloProxy_deleteRows_args&);
   AccumuloProxy_deleteRows_args() : login(), tableName(), startRow(), endRow() {
   }
 
-  virtual ~AccumuloProxy_deleteRows_args() throw() {}
-
+  virtual ~AccumuloProxy_deleteRows_args() throw();
   std::string login;
   std::string tableName;
   std::string startRow;
@@ -2061,21 +2020,13 @@
 
   _AccumuloProxy_deleteRows_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_startRow(const std::string& val) {
-    startRow = val;
-  }
+  void __set_startRow(const std::string& val);
 
-  void __set_endRow(const std::string& val) {
-    endRow = val;
-  }
+  void __set_endRow(const std::string& val);
 
   bool operator == (const AccumuloProxy_deleteRows_args & rhs) const
   {
@@ -2105,8 +2056,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_deleteRows_pargs() throw() {}
-
+  virtual ~AccumuloProxy_deleteRows_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* startRow;
@@ -2118,36 +2068,31 @@
 
 typedef struct _AccumuloProxy_deleteRows_result__isset {
   _AccumuloProxy_deleteRows_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_deleteRows_result__isset;
 
 class AccumuloProxy_deleteRows_result {
  public:
 
+  AccumuloProxy_deleteRows_result(const AccumuloProxy_deleteRows_result&);
+  AccumuloProxy_deleteRows_result& operator=(const AccumuloProxy_deleteRows_result&);
   AccumuloProxy_deleteRows_result() {
   }
 
-  virtual ~AccumuloProxy_deleteRows_result() throw() {}
-
+  virtual ~AccumuloProxy_deleteRows_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_deleteRows_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_deleteRows_result & rhs) const
   {
@@ -2172,17 +2117,16 @@
 
 typedef struct _AccumuloProxy_deleteRows_presult__isset {
   _AccumuloProxy_deleteRows_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_deleteRows_presult__isset;
 
 class AccumuloProxy_deleteRows_presult {
  public:
 
 
-  virtual ~AccumuloProxy_deleteRows_presult() throw() {}
-
+  virtual ~AccumuloProxy_deleteRows_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -2195,36 +2139,31 @@
 
 typedef struct _AccumuloProxy_exportTable_args__isset {
   _AccumuloProxy_exportTable_args__isset() : login(false), tableName(false), exportDir(false) {}
-  bool login;
-  bool tableName;
-  bool exportDir;
+  bool login :1;
+  bool tableName :1;
+  bool exportDir :1;
 } _AccumuloProxy_exportTable_args__isset;
 
 class AccumuloProxy_exportTable_args {
  public:
 
+  AccumuloProxy_exportTable_args(const AccumuloProxy_exportTable_args&);
+  AccumuloProxy_exportTable_args& operator=(const AccumuloProxy_exportTable_args&);
   AccumuloProxy_exportTable_args() : login(), tableName(), exportDir() {
   }
 
-  virtual ~AccumuloProxy_exportTable_args() throw() {}
-
+  virtual ~AccumuloProxy_exportTable_args() throw();
   std::string login;
   std::string tableName;
   std::string exportDir;
 
   _AccumuloProxy_exportTable_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_exportDir(const std::string& val) {
-    exportDir = val;
-  }
+  void __set_exportDir(const std::string& val);
 
   bool operator == (const AccumuloProxy_exportTable_args & rhs) const
   {
@@ -2252,8 +2191,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_exportTable_pargs() throw() {}
-
+  virtual ~AccumuloProxy_exportTable_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* exportDir;
@@ -2264,36 +2202,31 @@
 
 typedef struct _AccumuloProxy_exportTable_result__isset {
   _AccumuloProxy_exportTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_exportTable_result__isset;
 
 class AccumuloProxy_exportTable_result {
  public:
 
+  AccumuloProxy_exportTable_result(const AccumuloProxy_exportTable_result&);
+  AccumuloProxy_exportTable_result& operator=(const AccumuloProxy_exportTable_result&);
   AccumuloProxy_exportTable_result() {
   }
 
-  virtual ~AccumuloProxy_exportTable_result() throw() {}
-
+  virtual ~AccumuloProxy_exportTable_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_exportTable_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_exportTable_result & rhs) const
   {
@@ -2318,17 +2251,16 @@
 
 typedef struct _AccumuloProxy_exportTable_presult__isset {
   _AccumuloProxy_exportTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_exportTable_presult__isset;
 
 class AccumuloProxy_exportTable_presult {
  public:
 
 
-  virtual ~AccumuloProxy_exportTable_presult() throw() {}
-
+  virtual ~AccumuloProxy_exportTable_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -2341,21 +2273,22 @@
 
 typedef struct _AccumuloProxy_flushTable_args__isset {
   _AccumuloProxy_flushTable_args__isset() : login(false), tableName(false), startRow(false), endRow(false), wait(false) {}
-  bool login;
-  bool tableName;
-  bool startRow;
-  bool endRow;
-  bool wait;
+  bool login :1;
+  bool tableName :1;
+  bool startRow :1;
+  bool endRow :1;
+  bool wait :1;
 } _AccumuloProxy_flushTable_args__isset;
 
 class AccumuloProxy_flushTable_args {
  public:
 
+  AccumuloProxy_flushTable_args(const AccumuloProxy_flushTable_args&);
+  AccumuloProxy_flushTable_args& operator=(const AccumuloProxy_flushTable_args&);
   AccumuloProxy_flushTable_args() : login(), tableName(), startRow(), endRow(), wait(0) {
   }
 
-  virtual ~AccumuloProxy_flushTable_args() throw() {}
-
+  virtual ~AccumuloProxy_flushTable_args() throw();
   std::string login;
   std::string tableName;
   std::string startRow;
@@ -2364,25 +2297,15 @@
 
   _AccumuloProxy_flushTable_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_startRow(const std::string& val) {
-    startRow = val;
-  }
+  void __set_startRow(const std::string& val);
 
-  void __set_endRow(const std::string& val) {
-    endRow = val;
-  }
+  void __set_endRow(const std::string& val);
 
-  void __set_wait(const bool val) {
-    wait = val;
-  }
+  void __set_wait(const bool val);
 
   bool operator == (const AccumuloProxy_flushTable_args & rhs) const
   {
@@ -2414,8 +2337,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_flushTable_pargs() throw() {}
-
+  virtual ~AccumuloProxy_flushTable_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* startRow;
@@ -2428,36 +2350,31 @@
 
 typedef struct _AccumuloProxy_flushTable_result__isset {
   _AccumuloProxy_flushTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_flushTable_result__isset;
 
 class AccumuloProxy_flushTable_result {
  public:
 
+  AccumuloProxy_flushTable_result(const AccumuloProxy_flushTable_result&);
+  AccumuloProxy_flushTable_result& operator=(const AccumuloProxy_flushTable_result&);
   AccumuloProxy_flushTable_result() {
   }
 
-  virtual ~AccumuloProxy_flushTable_result() throw() {}
-
+  virtual ~AccumuloProxy_flushTable_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_flushTable_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_flushTable_result & rhs) const
   {
@@ -2482,17 +2399,16 @@
 
 typedef struct _AccumuloProxy_flushTable_presult__isset {
   _AccumuloProxy_flushTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_flushTable_presult__isset;
 
 class AccumuloProxy_flushTable_presult {
  public:
 
 
-  virtual ~AccumuloProxy_flushTable_presult() throw() {}
-
+  virtual ~AccumuloProxy_flushTable_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -2505,30 +2421,27 @@
 
 typedef struct _AccumuloProxy_getDiskUsage_args__isset {
   _AccumuloProxy_getDiskUsage_args__isset() : login(false), tables(false) {}
-  bool login;
-  bool tables;
+  bool login :1;
+  bool tables :1;
 } _AccumuloProxy_getDiskUsage_args__isset;
 
 class AccumuloProxy_getDiskUsage_args {
  public:
 
+  AccumuloProxy_getDiskUsage_args(const AccumuloProxy_getDiskUsage_args&);
+  AccumuloProxy_getDiskUsage_args& operator=(const AccumuloProxy_getDiskUsage_args&);
   AccumuloProxy_getDiskUsage_args() : login() {
   }
 
-  virtual ~AccumuloProxy_getDiskUsage_args() throw() {}
-
+  virtual ~AccumuloProxy_getDiskUsage_args() throw();
   std::string login;
   std::set<std::string>  tables;
 
   _AccumuloProxy_getDiskUsage_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tables(const std::set<std::string> & val) {
-    tables = val;
-  }
+  void __set_tables(const std::set<std::string> & val);
 
   bool operator == (const AccumuloProxy_getDiskUsage_args & rhs) const
   {
@@ -2554,8 +2467,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getDiskUsage_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getDiskUsage_pargs() throw();
   const std::string* login;
   const std::set<std::string> * tables;
 
@@ -2565,20 +2477,21 @@
 
 typedef struct _AccumuloProxy_getDiskUsage_result__isset {
   _AccumuloProxy_getDiskUsage_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_getDiskUsage_result__isset;
 
 class AccumuloProxy_getDiskUsage_result {
  public:
 
+  AccumuloProxy_getDiskUsage_result(const AccumuloProxy_getDiskUsage_result&);
+  AccumuloProxy_getDiskUsage_result& operator=(const AccumuloProxy_getDiskUsage_result&);
   AccumuloProxy_getDiskUsage_result() {
   }
 
-  virtual ~AccumuloProxy_getDiskUsage_result() throw() {}
-
+  virtual ~AccumuloProxy_getDiskUsage_result() throw();
   std::vector<DiskUsage>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -2586,21 +2499,13 @@
 
   _AccumuloProxy_getDiskUsage_result__isset __isset;
 
-  void __set_success(const std::vector<DiskUsage> & val) {
-    success = val;
-  }
+  void __set_success(const std::vector<DiskUsage> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_getDiskUsage_result & rhs) const
   {
@@ -2627,18 +2532,17 @@
 
 typedef struct _AccumuloProxy_getDiskUsage_presult__isset {
   _AccumuloProxy_getDiskUsage_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_getDiskUsage_presult__isset;
 
 class AccumuloProxy_getDiskUsage_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getDiskUsage_presult() throw() {}
-
+  virtual ~AccumuloProxy_getDiskUsage_presult() throw();
   std::vector<DiskUsage> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -2652,30 +2556,27 @@
 
 typedef struct _AccumuloProxy_getLocalityGroups_args__isset {
   _AccumuloProxy_getLocalityGroups_args__isset() : login(false), tableName(false) {}
-  bool login;
-  bool tableName;
+  bool login :1;
+  bool tableName :1;
 } _AccumuloProxy_getLocalityGroups_args__isset;
 
 class AccumuloProxy_getLocalityGroups_args {
  public:
 
+  AccumuloProxy_getLocalityGroups_args(const AccumuloProxy_getLocalityGroups_args&);
+  AccumuloProxy_getLocalityGroups_args& operator=(const AccumuloProxy_getLocalityGroups_args&);
   AccumuloProxy_getLocalityGroups_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_getLocalityGroups_args() throw() {}
-
+  virtual ~AccumuloProxy_getLocalityGroups_args() throw();
   std::string login;
   std::string tableName;
 
   _AccumuloProxy_getLocalityGroups_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
   bool operator == (const AccumuloProxy_getLocalityGroups_args & rhs) const
   {
@@ -2701,8 +2602,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getLocalityGroups_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getLocalityGroups_pargs() throw();
   const std::string* login;
   const std::string* tableName;
 
@@ -2712,20 +2612,21 @@
 
 typedef struct _AccumuloProxy_getLocalityGroups_result__isset {
   _AccumuloProxy_getLocalityGroups_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_getLocalityGroups_result__isset;
 
 class AccumuloProxy_getLocalityGroups_result {
  public:
 
+  AccumuloProxy_getLocalityGroups_result(const AccumuloProxy_getLocalityGroups_result&);
+  AccumuloProxy_getLocalityGroups_result& operator=(const AccumuloProxy_getLocalityGroups_result&);
   AccumuloProxy_getLocalityGroups_result() {
   }
 
-  virtual ~AccumuloProxy_getLocalityGroups_result() throw() {}
-
+  virtual ~AccumuloProxy_getLocalityGroups_result() throw();
   std::map<std::string, std::set<std::string> >  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -2733,21 +2634,13 @@
 
   _AccumuloProxy_getLocalityGroups_result__isset __isset;
 
-  void __set_success(const std::map<std::string, std::set<std::string> > & val) {
-    success = val;
-  }
+  void __set_success(const std::map<std::string, std::set<std::string> > & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_getLocalityGroups_result & rhs) const
   {
@@ -2774,18 +2667,17 @@
 
 typedef struct _AccumuloProxy_getLocalityGroups_presult__isset {
   _AccumuloProxy_getLocalityGroups_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_getLocalityGroups_presult__isset;
 
 class AccumuloProxy_getLocalityGroups_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getLocalityGroups_presult() throw() {}
-
+  virtual ~AccumuloProxy_getLocalityGroups_presult() throw();
   std::map<std::string, std::set<std::string> > * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -2799,20 +2691,21 @@
 
 typedef struct _AccumuloProxy_getIteratorSetting_args__isset {
   _AccumuloProxy_getIteratorSetting_args__isset() : login(false), tableName(false), iteratorName(false), scope(false) {}
-  bool login;
-  bool tableName;
-  bool iteratorName;
-  bool scope;
+  bool login :1;
+  bool tableName :1;
+  bool iteratorName :1;
+  bool scope :1;
 } _AccumuloProxy_getIteratorSetting_args__isset;
 
 class AccumuloProxy_getIteratorSetting_args {
  public:
 
+  AccumuloProxy_getIteratorSetting_args(const AccumuloProxy_getIteratorSetting_args&);
+  AccumuloProxy_getIteratorSetting_args& operator=(const AccumuloProxy_getIteratorSetting_args&);
   AccumuloProxy_getIteratorSetting_args() : login(), tableName(), iteratorName(), scope((IteratorScope::type)0) {
   }
 
-  virtual ~AccumuloProxy_getIteratorSetting_args() throw() {}
-
+  virtual ~AccumuloProxy_getIteratorSetting_args() throw();
   std::string login;
   std::string tableName;
   std::string iteratorName;
@@ -2820,21 +2713,13 @@
 
   _AccumuloProxy_getIteratorSetting_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_iteratorName(const std::string& val) {
-    iteratorName = val;
-  }
+  void __set_iteratorName(const std::string& val);
 
-  void __set_scope(const IteratorScope::type val) {
-    scope = val;
-  }
+  void __set_scope(const IteratorScope::type val);
 
   bool operator == (const AccumuloProxy_getIteratorSetting_args & rhs) const
   {
@@ -2864,8 +2749,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getIteratorSetting_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getIteratorSetting_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* iteratorName;
@@ -2877,20 +2761,21 @@
 
 typedef struct _AccumuloProxy_getIteratorSetting_result__isset {
   _AccumuloProxy_getIteratorSetting_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_getIteratorSetting_result__isset;
 
 class AccumuloProxy_getIteratorSetting_result {
  public:
 
+  AccumuloProxy_getIteratorSetting_result(const AccumuloProxy_getIteratorSetting_result&);
+  AccumuloProxy_getIteratorSetting_result& operator=(const AccumuloProxy_getIteratorSetting_result&);
   AccumuloProxy_getIteratorSetting_result() {
   }
 
-  virtual ~AccumuloProxy_getIteratorSetting_result() throw() {}
-
+  virtual ~AccumuloProxy_getIteratorSetting_result() throw();
   IteratorSetting success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -2898,21 +2783,13 @@
 
   _AccumuloProxy_getIteratorSetting_result__isset __isset;
 
-  void __set_success(const IteratorSetting& val) {
-    success = val;
-  }
+  void __set_success(const IteratorSetting& val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_getIteratorSetting_result & rhs) const
   {
@@ -2939,18 +2816,17 @@
 
 typedef struct _AccumuloProxy_getIteratorSetting_presult__isset {
   _AccumuloProxy_getIteratorSetting_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_getIteratorSetting_presult__isset;
 
 class AccumuloProxy_getIteratorSetting_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getIteratorSetting_presult() throw() {}
-
+  virtual ~AccumuloProxy_getIteratorSetting_presult() throw();
   IteratorSetting* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -2964,23 +2840,24 @@
 
 typedef struct _AccumuloProxy_getMaxRow_args__isset {
   _AccumuloProxy_getMaxRow_args__isset() : login(false), tableName(false), auths(false), startRow(false), startInclusive(false), endRow(false), endInclusive(false) {}
-  bool login;
-  bool tableName;
-  bool auths;
-  bool startRow;
-  bool startInclusive;
-  bool endRow;
-  bool endInclusive;
+  bool login :1;
+  bool tableName :1;
+  bool auths :1;
+  bool startRow :1;
+  bool startInclusive :1;
+  bool endRow :1;
+  bool endInclusive :1;
 } _AccumuloProxy_getMaxRow_args__isset;
 
 class AccumuloProxy_getMaxRow_args {
  public:
 
+  AccumuloProxy_getMaxRow_args(const AccumuloProxy_getMaxRow_args&);
+  AccumuloProxy_getMaxRow_args& operator=(const AccumuloProxy_getMaxRow_args&);
   AccumuloProxy_getMaxRow_args() : login(), tableName(), startRow(), startInclusive(0), endRow(), endInclusive(0) {
   }
 
-  virtual ~AccumuloProxy_getMaxRow_args() throw() {}
-
+  virtual ~AccumuloProxy_getMaxRow_args() throw();
   std::string login;
   std::string tableName;
   std::set<std::string>  auths;
@@ -2991,33 +2868,19 @@
 
   _AccumuloProxy_getMaxRow_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_auths(const std::set<std::string> & val) {
-    auths = val;
-  }
+  void __set_auths(const std::set<std::string> & val);
 
-  void __set_startRow(const std::string& val) {
-    startRow = val;
-  }
+  void __set_startRow(const std::string& val);
 
-  void __set_startInclusive(const bool val) {
-    startInclusive = val;
-  }
+  void __set_startInclusive(const bool val);
 
-  void __set_endRow(const std::string& val) {
-    endRow = val;
-  }
+  void __set_endRow(const std::string& val);
 
-  void __set_endInclusive(const bool val) {
-    endInclusive = val;
-  }
+  void __set_endInclusive(const bool val);
 
   bool operator == (const AccumuloProxy_getMaxRow_args & rhs) const
   {
@@ -3053,8 +2916,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getMaxRow_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getMaxRow_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::set<std::string> * auths;
@@ -3069,20 +2931,21 @@
 
 typedef struct _AccumuloProxy_getMaxRow_result__isset {
   _AccumuloProxy_getMaxRow_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_getMaxRow_result__isset;
 
 class AccumuloProxy_getMaxRow_result {
  public:
 
+  AccumuloProxy_getMaxRow_result(const AccumuloProxy_getMaxRow_result&);
+  AccumuloProxy_getMaxRow_result& operator=(const AccumuloProxy_getMaxRow_result&);
   AccumuloProxy_getMaxRow_result() : success() {
   }
 
-  virtual ~AccumuloProxy_getMaxRow_result() throw() {}
-
+  virtual ~AccumuloProxy_getMaxRow_result() throw();
   std::string success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -3090,21 +2953,13 @@
 
   _AccumuloProxy_getMaxRow_result__isset __isset;
 
-  void __set_success(const std::string& val) {
-    success = val;
-  }
+  void __set_success(const std::string& val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_getMaxRow_result & rhs) const
   {
@@ -3131,18 +2986,17 @@
 
 typedef struct _AccumuloProxy_getMaxRow_presult__isset {
   _AccumuloProxy_getMaxRow_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_getMaxRow_presult__isset;
 
 class AccumuloProxy_getMaxRow_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getMaxRow_presult() throw() {}
-
+  virtual ~AccumuloProxy_getMaxRow_presult() throw();
   std::string* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -3156,30 +3010,27 @@
 
 typedef struct _AccumuloProxy_getTableProperties_args__isset {
   _AccumuloProxy_getTableProperties_args__isset() : login(false), tableName(false) {}
-  bool login;
-  bool tableName;
+  bool login :1;
+  bool tableName :1;
 } _AccumuloProxy_getTableProperties_args__isset;
 
 class AccumuloProxy_getTableProperties_args {
  public:
 
+  AccumuloProxy_getTableProperties_args(const AccumuloProxy_getTableProperties_args&);
+  AccumuloProxy_getTableProperties_args& operator=(const AccumuloProxy_getTableProperties_args&);
   AccumuloProxy_getTableProperties_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_getTableProperties_args() throw() {}
-
+  virtual ~AccumuloProxy_getTableProperties_args() throw();
   std::string login;
   std::string tableName;
 
   _AccumuloProxy_getTableProperties_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
   bool operator == (const AccumuloProxy_getTableProperties_args & rhs) const
   {
@@ -3205,8 +3056,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getTableProperties_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getTableProperties_pargs() throw();
   const std::string* login;
   const std::string* tableName;
 
@@ -3216,20 +3066,21 @@
 
 typedef struct _AccumuloProxy_getTableProperties_result__isset {
   _AccumuloProxy_getTableProperties_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_getTableProperties_result__isset;
 
 class AccumuloProxy_getTableProperties_result {
  public:
 
+  AccumuloProxy_getTableProperties_result(const AccumuloProxy_getTableProperties_result&);
+  AccumuloProxy_getTableProperties_result& operator=(const AccumuloProxy_getTableProperties_result&);
   AccumuloProxy_getTableProperties_result() {
   }
 
-  virtual ~AccumuloProxy_getTableProperties_result() throw() {}
-
+  virtual ~AccumuloProxy_getTableProperties_result() throw();
   std::map<std::string, std::string>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -3237,21 +3088,13 @@
 
   _AccumuloProxy_getTableProperties_result__isset __isset;
 
-  void __set_success(const std::map<std::string, std::string> & val) {
-    success = val;
-  }
+  void __set_success(const std::map<std::string, std::string> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_getTableProperties_result & rhs) const
   {
@@ -3278,18 +3121,17 @@
 
 typedef struct _AccumuloProxy_getTableProperties_presult__isset {
   _AccumuloProxy_getTableProperties_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_getTableProperties_presult__isset;
 
 class AccumuloProxy_getTableProperties_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getTableProperties_presult() throw() {}
-
+  virtual ~AccumuloProxy_getTableProperties_presult() throw();
   std::map<std::string, std::string> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -3303,21 +3145,22 @@
 
 typedef struct _AccumuloProxy_importDirectory_args__isset {
   _AccumuloProxy_importDirectory_args__isset() : login(false), tableName(false), importDir(false), failureDir(false), setTime(false) {}
-  bool login;
-  bool tableName;
-  bool importDir;
-  bool failureDir;
-  bool setTime;
+  bool login :1;
+  bool tableName :1;
+  bool importDir :1;
+  bool failureDir :1;
+  bool setTime :1;
 } _AccumuloProxy_importDirectory_args__isset;
 
 class AccumuloProxy_importDirectory_args {
  public:
 
+  AccumuloProxy_importDirectory_args(const AccumuloProxy_importDirectory_args&);
+  AccumuloProxy_importDirectory_args& operator=(const AccumuloProxy_importDirectory_args&);
   AccumuloProxy_importDirectory_args() : login(), tableName(), importDir(), failureDir(), setTime(0) {
   }
 
-  virtual ~AccumuloProxy_importDirectory_args() throw() {}
-
+  virtual ~AccumuloProxy_importDirectory_args() throw();
   std::string login;
   std::string tableName;
   std::string importDir;
@@ -3326,25 +3169,15 @@
 
   _AccumuloProxy_importDirectory_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_importDir(const std::string& val) {
-    importDir = val;
-  }
+  void __set_importDir(const std::string& val);
 
-  void __set_failureDir(const std::string& val) {
-    failureDir = val;
-  }
+  void __set_failureDir(const std::string& val);
 
-  void __set_setTime(const bool val) {
-    setTime = val;
-  }
+  void __set_setTime(const bool val);
 
   bool operator == (const AccumuloProxy_importDirectory_args & rhs) const
   {
@@ -3376,8 +3209,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_importDirectory_pargs() throw() {}
-
+  virtual ~AccumuloProxy_importDirectory_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* importDir;
@@ -3390,36 +3222,31 @@
 
 typedef struct _AccumuloProxy_importDirectory_result__isset {
   _AccumuloProxy_importDirectory_result__isset() : ouch1(false), ouch3(false), ouch4(false) {}
-  bool ouch1;
-  bool ouch3;
-  bool ouch4;
+  bool ouch1 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
 } _AccumuloProxy_importDirectory_result__isset;
 
 class AccumuloProxy_importDirectory_result {
  public:
 
+  AccumuloProxy_importDirectory_result(const AccumuloProxy_importDirectory_result&);
+  AccumuloProxy_importDirectory_result& operator=(const AccumuloProxy_importDirectory_result&);
   AccumuloProxy_importDirectory_result() {
   }
 
-  virtual ~AccumuloProxy_importDirectory_result() throw() {}
-
+  virtual ~AccumuloProxy_importDirectory_result() throw();
   TableNotFoundException ouch1;
   AccumuloException ouch3;
   AccumuloSecurityException ouch4;
 
   _AccumuloProxy_importDirectory_result__isset __isset;
 
-  void __set_ouch1(const TableNotFoundException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const TableNotFoundException& val);
 
-  void __set_ouch3(const AccumuloException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const AccumuloException& val);
 
-  void __set_ouch4(const AccumuloSecurityException& val) {
-    ouch4 = val;
-  }
+  void __set_ouch4(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_importDirectory_result & rhs) const
   {
@@ -3444,17 +3271,16 @@
 
 typedef struct _AccumuloProxy_importDirectory_presult__isset {
   _AccumuloProxy_importDirectory_presult__isset() : ouch1(false), ouch3(false), ouch4(false) {}
-  bool ouch1;
-  bool ouch3;
-  bool ouch4;
+  bool ouch1 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
 } _AccumuloProxy_importDirectory_presult__isset;
 
 class AccumuloProxy_importDirectory_presult {
  public:
 
 
-  virtual ~AccumuloProxy_importDirectory_presult() throw() {}
-
+  virtual ~AccumuloProxy_importDirectory_presult() throw();
   TableNotFoundException ouch1;
   AccumuloException ouch3;
   AccumuloSecurityException ouch4;
@@ -3467,36 +3293,31 @@
 
 typedef struct _AccumuloProxy_importTable_args__isset {
   _AccumuloProxy_importTable_args__isset() : login(false), tableName(false), importDir(false) {}
-  bool login;
-  bool tableName;
-  bool importDir;
+  bool login :1;
+  bool tableName :1;
+  bool importDir :1;
 } _AccumuloProxy_importTable_args__isset;
 
 class AccumuloProxy_importTable_args {
  public:
 
+  AccumuloProxy_importTable_args(const AccumuloProxy_importTable_args&);
+  AccumuloProxy_importTable_args& operator=(const AccumuloProxy_importTable_args&);
   AccumuloProxy_importTable_args() : login(), tableName(), importDir() {
   }
 
-  virtual ~AccumuloProxy_importTable_args() throw() {}
-
+  virtual ~AccumuloProxy_importTable_args() throw();
   std::string login;
   std::string tableName;
   std::string importDir;
 
   _AccumuloProxy_importTable_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_importDir(const std::string& val) {
-    importDir = val;
-  }
+  void __set_importDir(const std::string& val);
 
   bool operator == (const AccumuloProxy_importTable_args & rhs) const
   {
@@ -3524,8 +3345,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_importTable_pargs() throw() {}
-
+  virtual ~AccumuloProxy_importTable_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* importDir;
@@ -3536,36 +3356,31 @@
 
 typedef struct _AccumuloProxy_importTable_result__isset {
   _AccumuloProxy_importTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_importTable_result__isset;
 
 class AccumuloProxy_importTable_result {
  public:
 
+  AccumuloProxy_importTable_result(const AccumuloProxy_importTable_result&);
+  AccumuloProxy_importTable_result& operator=(const AccumuloProxy_importTable_result&);
   AccumuloProxy_importTable_result() {
   }
 
-  virtual ~AccumuloProxy_importTable_result() throw() {}
-
+  virtual ~AccumuloProxy_importTable_result() throw();
   TableExistsException ouch1;
   AccumuloException ouch2;
   AccumuloSecurityException ouch3;
 
   _AccumuloProxy_importTable_result__isset __isset;
 
-  void __set_ouch1(const TableExistsException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const TableExistsException& val);
 
-  void __set_ouch2(const AccumuloException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloException& val);
 
-  void __set_ouch3(const AccumuloSecurityException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_importTable_result & rhs) const
   {
@@ -3590,17 +3405,16 @@
 
 typedef struct _AccumuloProxy_importTable_presult__isset {
   _AccumuloProxy_importTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_importTable_presult__isset;
 
 class AccumuloProxy_importTable_presult {
  public:
 
 
-  virtual ~AccumuloProxy_importTable_presult() throw() {}
-
+  virtual ~AccumuloProxy_importTable_presult() throw();
   TableExistsException ouch1;
   AccumuloException ouch2;
   AccumuloSecurityException ouch3;
@@ -3613,36 +3427,31 @@
 
 typedef struct _AccumuloProxy_listSplits_args__isset {
   _AccumuloProxy_listSplits_args__isset() : login(false), tableName(false), maxSplits(false) {}
-  bool login;
-  bool tableName;
-  bool maxSplits;
+  bool login :1;
+  bool tableName :1;
+  bool maxSplits :1;
 } _AccumuloProxy_listSplits_args__isset;
 
 class AccumuloProxy_listSplits_args {
  public:
 
+  AccumuloProxy_listSplits_args(const AccumuloProxy_listSplits_args&);
+  AccumuloProxy_listSplits_args& operator=(const AccumuloProxy_listSplits_args&);
   AccumuloProxy_listSplits_args() : login(), tableName(), maxSplits(0) {
   }
 
-  virtual ~AccumuloProxy_listSplits_args() throw() {}
-
+  virtual ~AccumuloProxy_listSplits_args() throw();
   std::string login;
   std::string tableName;
   int32_t maxSplits;
 
   _AccumuloProxy_listSplits_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_maxSplits(const int32_t val) {
-    maxSplits = val;
-  }
+  void __set_maxSplits(const int32_t val);
 
   bool operator == (const AccumuloProxy_listSplits_args & rhs) const
   {
@@ -3670,8 +3479,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_listSplits_pargs() throw() {}
-
+  virtual ~AccumuloProxy_listSplits_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const int32_t* maxSplits;
@@ -3682,20 +3490,21 @@
 
 typedef struct _AccumuloProxy_listSplits_result__isset {
   _AccumuloProxy_listSplits_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_listSplits_result__isset;
 
 class AccumuloProxy_listSplits_result {
  public:
 
+  AccumuloProxy_listSplits_result(const AccumuloProxy_listSplits_result&);
+  AccumuloProxy_listSplits_result& operator=(const AccumuloProxy_listSplits_result&);
   AccumuloProxy_listSplits_result() {
   }
 
-  virtual ~AccumuloProxy_listSplits_result() throw() {}
-
+  virtual ~AccumuloProxy_listSplits_result() throw();
   std::vector<std::string>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -3703,21 +3512,13 @@
 
   _AccumuloProxy_listSplits_result__isset __isset;
 
-  void __set_success(const std::vector<std::string> & val) {
-    success = val;
-  }
+  void __set_success(const std::vector<std::string> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_listSplits_result & rhs) const
   {
@@ -3744,18 +3545,17 @@
 
 typedef struct _AccumuloProxy_listSplits_presult__isset {
   _AccumuloProxy_listSplits_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_listSplits_presult__isset;
 
 class AccumuloProxy_listSplits_presult {
  public:
 
 
-  virtual ~AccumuloProxy_listSplits_presult() throw() {}
-
+  virtual ~AccumuloProxy_listSplits_presult() throw();
   std::vector<std::string> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -3769,24 +3569,23 @@
 
 typedef struct _AccumuloProxy_listTables_args__isset {
   _AccumuloProxy_listTables_args__isset() : login(false) {}
-  bool login;
+  bool login :1;
 } _AccumuloProxy_listTables_args__isset;
 
 class AccumuloProxy_listTables_args {
  public:
 
+  AccumuloProxy_listTables_args(const AccumuloProxy_listTables_args&);
+  AccumuloProxy_listTables_args& operator=(const AccumuloProxy_listTables_args&);
   AccumuloProxy_listTables_args() : login() {
   }
 
-  virtual ~AccumuloProxy_listTables_args() throw() {}
-
+  virtual ~AccumuloProxy_listTables_args() throw();
   std::string login;
 
   _AccumuloProxy_listTables_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
   bool operator == (const AccumuloProxy_listTables_args & rhs) const
   {
@@ -3810,8 +3609,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_listTables_pargs() throw() {}
-
+  virtual ~AccumuloProxy_listTables_pargs() throw();
   const std::string* login;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -3820,24 +3618,23 @@
 
 typedef struct _AccumuloProxy_listTables_result__isset {
   _AccumuloProxy_listTables_result__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_listTables_result__isset;
 
 class AccumuloProxy_listTables_result {
  public:
 
+  AccumuloProxy_listTables_result(const AccumuloProxy_listTables_result&);
+  AccumuloProxy_listTables_result& operator=(const AccumuloProxy_listTables_result&);
   AccumuloProxy_listTables_result() {
   }
 
-  virtual ~AccumuloProxy_listTables_result() throw() {}
-
+  virtual ~AccumuloProxy_listTables_result() throw();
   std::set<std::string>  success;
 
   _AccumuloProxy_listTables_result__isset __isset;
 
-  void __set_success(const std::set<std::string> & val) {
-    success = val;
-  }
+  void __set_success(const std::set<std::string> & val);
 
   bool operator == (const AccumuloProxy_listTables_result & rhs) const
   {
@@ -3858,15 +3655,14 @@
 
 typedef struct _AccumuloProxy_listTables_presult__isset {
   _AccumuloProxy_listTables_presult__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_listTables_presult__isset;
 
 class AccumuloProxy_listTables_presult {
  public:
 
 
-  virtual ~AccumuloProxy_listTables_presult() throw() {}
-
+  virtual ~AccumuloProxy_listTables_presult() throw();
   std::set<std::string> * success;
 
   _AccumuloProxy_listTables_presult__isset __isset;
@@ -3877,30 +3673,27 @@
 
 typedef struct _AccumuloProxy_listIterators_args__isset {
   _AccumuloProxy_listIterators_args__isset() : login(false), tableName(false) {}
-  bool login;
-  bool tableName;
+  bool login :1;
+  bool tableName :1;
 } _AccumuloProxy_listIterators_args__isset;
 
 class AccumuloProxy_listIterators_args {
  public:
 
+  AccumuloProxy_listIterators_args(const AccumuloProxy_listIterators_args&);
+  AccumuloProxy_listIterators_args& operator=(const AccumuloProxy_listIterators_args&);
   AccumuloProxy_listIterators_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_listIterators_args() throw() {}
-
+  virtual ~AccumuloProxy_listIterators_args() throw();
   std::string login;
   std::string tableName;
 
   _AccumuloProxy_listIterators_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
   bool operator == (const AccumuloProxy_listIterators_args & rhs) const
   {
@@ -3926,8 +3719,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_listIterators_pargs() throw() {}
-
+  virtual ~AccumuloProxy_listIterators_pargs() throw();
   const std::string* login;
   const std::string* tableName;
 
@@ -3937,20 +3729,21 @@
 
 typedef struct _AccumuloProxy_listIterators_result__isset {
   _AccumuloProxy_listIterators_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_listIterators_result__isset;
 
 class AccumuloProxy_listIterators_result {
  public:
 
+  AccumuloProxy_listIterators_result(const AccumuloProxy_listIterators_result&);
+  AccumuloProxy_listIterators_result& operator=(const AccumuloProxy_listIterators_result&);
   AccumuloProxy_listIterators_result() {
   }
 
-  virtual ~AccumuloProxy_listIterators_result() throw() {}
-
+  virtual ~AccumuloProxy_listIterators_result() throw();
   std::map<std::string, std::set<IteratorScope::type> >  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -3958,21 +3751,13 @@
 
   _AccumuloProxy_listIterators_result__isset __isset;
 
-  void __set_success(const std::map<std::string, std::set<IteratorScope::type> > & val) {
-    success = val;
-  }
+  void __set_success(const std::map<std::string, std::set<IteratorScope::type> > & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_listIterators_result & rhs) const
   {
@@ -3999,18 +3784,17 @@
 
 typedef struct _AccumuloProxy_listIterators_presult__isset {
   _AccumuloProxy_listIterators_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_listIterators_presult__isset;
 
 class AccumuloProxy_listIterators_presult {
  public:
 
 
-  virtual ~AccumuloProxy_listIterators_presult() throw() {}
-
+  virtual ~AccumuloProxy_listIterators_presult() throw();
   std::map<std::string, std::set<IteratorScope::type> > * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -4024,30 +3808,27 @@
 
 typedef struct _AccumuloProxy_listConstraints_args__isset {
   _AccumuloProxy_listConstraints_args__isset() : login(false), tableName(false) {}
-  bool login;
-  bool tableName;
+  bool login :1;
+  bool tableName :1;
 } _AccumuloProxy_listConstraints_args__isset;
 
 class AccumuloProxy_listConstraints_args {
  public:
 
+  AccumuloProxy_listConstraints_args(const AccumuloProxy_listConstraints_args&);
+  AccumuloProxy_listConstraints_args& operator=(const AccumuloProxy_listConstraints_args&);
   AccumuloProxy_listConstraints_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_listConstraints_args() throw() {}
-
+  virtual ~AccumuloProxy_listConstraints_args() throw();
   std::string login;
   std::string tableName;
 
   _AccumuloProxy_listConstraints_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
   bool operator == (const AccumuloProxy_listConstraints_args & rhs) const
   {
@@ -4073,8 +3854,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_listConstraints_pargs() throw() {}
-
+  virtual ~AccumuloProxy_listConstraints_pargs() throw();
   const std::string* login;
   const std::string* tableName;
 
@@ -4084,20 +3864,21 @@
 
 typedef struct _AccumuloProxy_listConstraints_result__isset {
   _AccumuloProxy_listConstraints_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_listConstraints_result__isset;
 
 class AccumuloProxy_listConstraints_result {
  public:
 
+  AccumuloProxy_listConstraints_result(const AccumuloProxy_listConstraints_result&);
+  AccumuloProxy_listConstraints_result& operator=(const AccumuloProxy_listConstraints_result&);
   AccumuloProxy_listConstraints_result() {
   }
 
-  virtual ~AccumuloProxy_listConstraints_result() throw() {}
-
+  virtual ~AccumuloProxy_listConstraints_result() throw();
   std::map<std::string, int32_t>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -4105,21 +3886,13 @@
 
   _AccumuloProxy_listConstraints_result__isset __isset;
 
-  void __set_success(const std::map<std::string, int32_t> & val) {
-    success = val;
-  }
+  void __set_success(const std::map<std::string, int32_t> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_listConstraints_result & rhs) const
   {
@@ -4146,18 +3919,17 @@
 
 typedef struct _AccumuloProxy_listConstraints_presult__isset {
   _AccumuloProxy_listConstraints_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_listConstraints_presult__isset;
 
 class AccumuloProxy_listConstraints_presult {
  public:
 
 
-  virtual ~AccumuloProxy_listConstraints_presult() throw() {}
-
+  virtual ~AccumuloProxy_listConstraints_presult() throw();
   std::map<std::string, int32_t> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -4171,20 +3943,21 @@
 
 typedef struct _AccumuloProxy_mergeTablets_args__isset {
   _AccumuloProxy_mergeTablets_args__isset() : login(false), tableName(false), startRow(false), endRow(false) {}
-  bool login;
-  bool tableName;
-  bool startRow;
-  bool endRow;
+  bool login :1;
+  bool tableName :1;
+  bool startRow :1;
+  bool endRow :1;
 } _AccumuloProxy_mergeTablets_args__isset;
 
 class AccumuloProxy_mergeTablets_args {
  public:
 
+  AccumuloProxy_mergeTablets_args(const AccumuloProxy_mergeTablets_args&);
+  AccumuloProxy_mergeTablets_args& operator=(const AccumuloProxy_mergeTablets_args&);
   AccumuloProxy_mergeTablets_args() : login(), tableName(), startRow(), endRow() {
   }
 
-  virtual ~AccumuloProxy_mergeTablets_args() throw() {}
-
+  virtual ~AccumuloProxy_mergeTablets_args() throw();
   std::string login;
   std::string tableName;
   std::string startRow;
@@ -4192,21 +3965,13 @@
 
   _AccumuloProxy_mergeTablets_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_startRow(const std::string& val) {
-    startRow = val;
-  }
+  void __set_startRow(const std::string& val);
 
-  void __set_endRow(const std::string& val) {
-    endRow = val;
-  }
+  void __set_endRow(const std::string& val);
 
   bool operator == (const AccumuloProxy_mergeTablets_args & rhs) const
   {
@@ -4236,8 +4001,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_mergeTablets_pargs() throw() {}
-
+  virtual ~AccumuloProxy_mergeTablets_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* startRow;
@@ -4249,36 +4013,31 @@
 
 typedef struct _AccumuloProxy_mergeTablets_result__isset {
   _AccumuloProxy_mergeTablets_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_mergeTablets_result__isset;
 
 class AccumuloProxy_mergeTablets_result {
  public:
 
+  AccumuloProxy_mergeTablets_result(const AccumuloProxy_mergeTablets_result&);
+  AccumuloProxy_mergeTablets_result& operator=(const AccumuloProxy_mergeTablets_result&);
   AccumuloProxy_mergeTablets_result() {
   }
 
-  virtual ~AccumuloProxy_mergeTablets_result() throw() {}
-
+  virtual ~AccumuloProxy_mergeTablets_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_mergeTablets_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_mergeTablets_result & rhs) const
   {
@@ -4303,17 +4062,16 @@
 
 typedef struct _AccumuloProxy_mergeTablets_presult__isset {
   _AccumuloProxy_mergeTablets_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_mergeTablets_presult__isset;
 
 class AccumuloProxy_mergeTablets_presult {
  public:
 
 
-  virtual ~AccumuloProxy_mergeTablets_presult() throw() {}
-
+  virtual ~AccumuloProxy_mergeTablets_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -4326,36 +4084,31 @@
 
 typedef struct _AccumuloProxy_offlineTable_args__isset {
   _AccumuloProxy_offlineTable_args__isset() : login(false), tableName(false), wait(true) {}
-  bool login;
-  bool tableName;
-  bool wait;
+  bool login :1;
+  bool tableName :1;
+  bool wait :1;
 } _AccumuloProxy_offlineTable_args__isset;
 
 class AccumuloProxy_offlineTable_args {
  public:
 
+  AccumuloProxy_offlineTable_args(const AccumuloProxy_offlineTable_args&);
+  AccumuloProxy_offlineTable_args& operator=(const AccumuloProxy_offlineTable_args&);
   AccumuloProxy_offlineTable_args() : login(), tableName(), wait(false) {
   }
 
-  virtual ~AccumuloProxy_offlineTable_args() throw() {}
-
+  virtual ~AccumuloProxy_offlineTable_args() throw();
   std::string login;
   std::string tableName;
   bool wait;
 
   _AccumuloProxy_offlineTable_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_wait(const bool val) {
-    wait = val;
-  }
+  void __set_wait(const bool val);
 
   bool operator == (const AccumuloProxy_offlineTable_args & rhs) const
   {
@@ -4383,8 +4136,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_offlineTable_pargs() throw() {}
-
+  virtual ~AccumuloProxy_offlineTable_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const bool* wait;
@@ -4395,36 +4147,31 @@
 
 typedef struct _AccumuloProxy_offlineTable_result__isset {
   _AccumuloProxy_offlineTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_offlineTable_result__isset;
 
 class AccumuloProxy_offlineTable_result {
  public:
 
+  AccumuloProxy_offlineTable_result(const AccumuloProxy_offlineTable_result&);
+  AccumuloProxy_offlineTable_result& operator=(const AccumuloProxy_offlineTable_result&);
   AccumuloProxy_offlineTable_result() {
   }
 
-  virtual ~AccumuloProxy_offlineTable_result() throw() {}
-
+  virtual ~AccumuloProxy_offlineTable_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_offlineTable_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_offlineTable_result & rhs) const
   {
@@ -4449,17 +4196,16 @@
 
 typedef struct _AccumuloProxy_offlineTable_presult__isset {
   _AccumuloProxy_offlineTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_offlineTable_presult__isset;
 
 class AccumuloProxy_offlineTable_presult {
  public:
 
 
-  virtual ~AccumuloProxy_offlineTable_presult() throw() {}
-
+  virtual ~AccumuloProxy_offlineTable_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -4472,36 +4218,31 @@
 
 typedef struct _AccumuloProxy_onlineTable_args__isset {
   _AccumuloProxy_onlineTable_args__isset() : login(false), tableName(false), wait(true) {}
-  bool login;
-  bool tableName;
-  bool wait;
+  bool login :1;
+  bool tableName :1;
+  bool wait :1;
 } _AccumuloProxy_onlineTable_args__isset;
 
 class AccumuloProxy_onlineTable_args {
  public:
 
+  AccumuloProxy_onlineTable_args(const AccumuloProxy_onlineTable_args&);
+  AccumuloProxy_onlineTable_args& operator=(const AccumuloProxy_onlineTable_args&);
   AccumuloProxy_onlineTable_args() : login(), tableName(), wait(false) {
   }
 
-  virtual ~AccumuloProxy_onlineTable_args() throw() {}
-
+  virtual ~AccumuloProxy_onlineTable_args() throw();
   std::string login;
   std::string tableName;
   bool wait;
 
   _AccumuloProxy_onlineTable_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_wait(const bool val) {
-    wait = val;
-  }
+  void __set_wait(const bool val);
 
   bool operator == (const AccumuloProxy_onlineTable_args & rhs) const
   {
@@ -4529,8 +4270,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_onlineTable_pargs() throw() {}
-
+  virtual ~AccumuloProxy_onlineTable_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const bool* wait;
@@ -4541,36 +4281,31 @@
 
 typedef struct _AccumuloProxy_onlineTable_result__isset {
   _AccumuloProxy_onlineTable_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_onlineTable_result__isset;
 
 class AccumuloProxy_onlineTable_result {
  public:
 
+  AccumuloProxy_onlineTable_result(const AccumuloProxy_onlineTable_result&);
+  AccumuloProxy_onlineTable_result& operator=(const AccumuloProxy_onlineTable_result&);
   AccumuloProxy_onlineTable_result() {
   }
 
-  virtual ~AccumuloProxy_onlineTable_result() throw() {}
-
+  virtual ~AccumuloProxy_onlineTable_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_onlineTable_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_onlineTable_result & rhs) const
   {
@@ -4595,17 +4330,16 @@
 
 typedef struct _AccumuloProxy_onlineTable_presult__isset {
   _AccumuloProxy_onlineTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_onlineTable_presult__isset;
 
 class AccumuloProxy_onlineTable_presult {
  public:
 
 
-  virtual ~AccumuloProxy_onlineTable_presult() throw() {}
-
+  virtual ~AccumuloProxy_onlineTable_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -4618,36 +4352,31 @@
 
 typedef struct _AccumuloProxy_removeConstraint_args__isset {
   _AccumuloProxy_removeConstraint_args__isset() : login(false), tableName(false), constraint(false) {}
-  bool login;
-  bool tableName;
-  bool constraint;
+  bool login :1;
+  bool tableName :1;
+  bool constraint :1;
 } _AccumuloProxy_removeConstraint_args__isset;
 
 class AccumuloProxy_removeConstraint_args {
  public:
 
+  AccumuloProxy_removeConstraint_args(const AccumuloProxy_removeConstraint_args&);
+  AccumuloProxy_removeConstraint_args& operator=(const AccumuloProxy_removeConstraint_args&);
   AccumuloProxy_removeConstraint_args() : login(), tableName(), constraint(0) {
   }
 
-  virtual ~AccumuloProxy_removeConstraint_args() throw() {}
-
+  virtual ~AccumuloProxy_removeConstraint_args() throw();
   std::string login;
   std::string tableName;
   int32_t constraint;
 
   _AccumuloProxy_removeConstraint_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_constraint(const int32_t val) {
-    constraint = val;
-  }
+  void __set_constraint(const int32_t val);
 
   bool operator == (const AccumuloProxy_removeConstraint_args & rhs) const
   {
@@ -4675,8 +4404,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_removeConstraint_pargs() throw() {}
-
+  virtual ~AccumuloProxy_removeConstraint_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const int32_t* constraint;
@@ -4687,36 +4415,31 @@
 
 typedef struct _AccumuloProxy_removeConstraint_result__isset {
   _AccumuloProxy_removeConstraint_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_removeConstraint_result__isset;
 
 class AccumuloProxy_removeConstraint_result {
  public:
 
+  AccumuloProxy_removeConstraint_result(const AccumuloProxy_removeConstraint_result&);
+  AccumuloProxy_removeConstraint_result& operator=(const AccumuloProxy_removeConstraint_result&);
   AccumuloProxy_removeConstraint_result() {
   }
 
-  virtual ~AccumuloProxy_removeConstraint_result() throw() {}
-
+  virtual ~AccumuloProxy_removeConstraint_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_removeConstraint_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_removeConstraint_result & rhs) const
   {
@@ -4741,17 +4464,16 @@
 
 typedef struct _AccumuloProxy_removeConstraint_presult__isset {
   _AccumuloProxy_removeConstraint_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_removeConstraint_presult__isset;
 
 class AccumuloProxy_removeConstraint_presult {
  public:
 
 
-  virtual ~AccumuloProxy_removeConstraint_presult() throw() {}
-
+  virtual ~AccumuloProxy_removeConstraint_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -4764,20 +4486,21 @@
 
 typedef struct _AccumuloProxy_removeIterator_args__isset {
   _AccumuloProxy_removeIterator_args__isset() : login(false), tableName(false), iterName(false), scopes(false) {}
-  bool login;
-  bool tableName;
-  bool iterName;
-  bool scopes;
+  bool login :1;
+  bool tableName :1;
+  bool iterName :1;
+  bool scopes :1;
 } _AccumuloProxy_removeIterator_args__isset;
 
 class AccumuloProxy_removeIterator_args {
  public:
 
+  AccumuloProxy_removeIterator_args(const AccumuloProxy_removeIterator_args&);
+  AccumuloProxy_removeIterator_args& operator=(const AccumuloProxy_removeIterator_args&);
   AccumuloProxy_removeIterator_args() : login(), tableName(), iterName() {
   }
 
-  virtual ~AccumuloProxy_removeIterator_args() throw() {}
-
+  virtual ~AccumuloProxy_removeIterator_args() throw();
   std::string login;
   std::string tableName;
   std::string iterName;
@@ -4785,21 +4508,13 @@
 
   _AccumuloProxy_removeIterator_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_iterName(const std::string& val) {
-    iterName = val;
-  }
+  void __set_iterName(const std::string& val);
 
-  void __set_scopes(const std::set<IteratorScope::type> & val) {
-    scopes = val;
-  }
+  void __set_scopes(const std::set<IteratorScope::type> & val);
 
   bool operator == (const AccumuloProxy_removeIterator_args & rhs) const
   {
@@ -4829,8 +4544,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_removeIterator_pargs() throw() {}
-
+  virtual ~AccumuloProxy_removeIterator_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* iterName;
@@ -4842,36 +4556,31 @@
 
 typedef struct _AccumuloProxy_removeIterator_result__isset {
   _AccumuloProxy_removeIterator_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_removeIterator_result__isset;
 
 class AccumuloProxy_removeIterator_result {
  public:
 
+  AccumuloProxy_removeIterator_result(const AccumuloProxy_removeIterator_result&);
+  AccumuloProxy_removeIterator_result& operator=(const AccumuloProxy_removeIterator_result&);
   AccumuloProxy_removeIterator_result() {
   }
 
-  virtual ~AccumuloProxy_removeIterator_result() throw() {}
-
+  virtual ~AccumuloProxy_removeIterator_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_removeIterator_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_removeIterator_result & rhs) const
   {
@@ -4896,17 +4605,16 @@
 
 typedef struct _AccumuloProxy_removeIterator_presult__isset {
   _AccumuloProxy_removeIterator_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_removeIterator_presult__isset;
 
 class AccumuloProxy_removeIterator_presult {
  public:
 
 
-  virtual ~AccumuloProxy_removeIterator_presult() throw() {}
-
+  virtual ~AccumuloProxy_removeIterator_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -4919,36 +4627,31 @@
 
 typedef struct _AccumuloProxy_removeTableProperty_args__isset {
   _AccumuloProxy_removeTableProperty_args__isset() : login(false), tableName(false), property(false) {}
-  bool login;
-  bool tableName;
-  bool property;
+  bool login :1;
+  bool tableName :1;
+  bool property :1;
 } _AccumuloProxy_removeTableProperty_args__isset;
 
 class AccumuloProxy_removeTableProperty_args {
  public:
 
+  AccumuloProxy_removeTableProperty_args(const AccumuloProxy_removeTableProperty_args&);
+  AccumuloProxy_removeTableProperty_args& operator=(const AccumuloProxy_removeTableProperty_args&);
   AccumuloProxy_removeTableProperty_args() : login(), tableName(), property() {
   }
 
-  virtual ~AccumuloProxy_removeTableProperty_args() throw() {}
-
+  virtual ~AccumuloProxy_removeTableProperty_args() throw();
   std::string login;
   std::string tableName;
   std::string property;
 
   _AccumuloProxy_removeTableProperty_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_property(const std::string& val) {
-    property = val;
-  }
+  void __set_property(const std::string& val);
 
   bool operator == (const AccumuloProxy_removeTableProperty_args & rhs) const
   {
@@ -4976,8 +4679,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_removeTableProperty_pargs() throw() {}
-
+  virtual ~AccumuloProxy_removeTableProperty_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* property;
@@ -4988,36 +4690,31 @@
 
 typedef struct _AccumuloProxy_removeTableProperty_result__isset {
   _AccumuloProxy_removeTableProperty_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_removeTableProperty_result__isset;
 
 class AccumuloProxy_removeTableProperty_result {
  public:
 
+  AccumuloProxy_removeTableProperty_result(const AccumuloProxy_removeTableProperty_result&);
+  AccumuloProxy_removeTableProperty_result& operator=(const AccumuloProxy_removeTableProperty_result&);
   AccumuloProxy_removeTableProperty_result() {
   }
 
-  virtual ~AccumuloProxy_removeTableProperty_result() throw() {}
-
+  virtual ~AccumuloProxy_removeTableProperty_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_removeTableProperty_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_removeTableProperty_result & rhs) const
   {
@@ -5042,17 +4739,16 @@
 
 typedef struct _AccumuloProxy_removeTableProperty_presult__isset {
   _AccumuloProxy_removeTableProperty_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_removeTableProperty_presult__isset;
 
 class AccumuloProxy_removeTableProperty_presult {
  public:
 
 
-  virtual ~AccumuloProxy_removeTableProperty_presult() throw() {}
-
+  virtual ~AccumuloProxy_removeTableProperty_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -5065,36 +4761,31 @@
 
 typedef struct _AccumuloProxy_renameTable_args__isset {
   _AccumuloProxy_renameTable_args__isset() : login(false), oldTableName(false), newTableName(false) {}
-  bool login;
-  bool oldTableName;
-  bool newTableName;
+  bool login :1;
+  bool oldTableName :1;
+  bool newTableName :1;
 } _AccumuloProxy_renameTable_args__isset;
 
 class AccumuloProxy_renameTable_args {
  public:
 
+  AccumuloProxy_renameTable_args(const AccumuloProxy_renameTable_args&);
+  AccumuloProxy_renameTable_args& operator=(const AccumuloProxy_renameTable_args&);
   AccumuloProxy_renameTable_args() : login(), oldTableName(), newTableName() {
   }
 
-  virtual ~AccumuloProxy_renameTable_args() throw() {}
-
+  virtual ~AccumuloProxy_renameTable_args() throw();
   std::string login;
   std::string oldTableName;
   std::string newTableName;
 
   _AccumuloProxy_renameTable_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_oldTableName(const std::string& val) {
-    oldTableName = val;
-  }
+  void __set_oldTableName(const std::string& val);
 
-  void __set_newTableName(const std::string& val) {
-    newTableName = val;
-  }
+  void __set_newTableName(const std::string& val);
 
   bool operator == (const AccumuloProxy_renameTable_args & rhs) const
   {
@@ -5122,8 +4813,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_renameTable_pargs() throw() {}
-
+  virtual ~AccumuloProxy_renameTable_pargs() throw();
   const std::string* login;
   const std::string* oldTableName;
   const std::string* newTableName;
@@ -5134,20 +4824,21 @@
 
 typedef struct _AccumuloProxy_renameTable_result__isset {
   _AccumuloProxy_renameTable_result__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
-  bool ouch4;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
 } _AccumuloProxy_renameTable_result__isset;
 
 class AccumuloProxy_renameTable_result {
  public:
 
+  AccumuloProxy_renameTable_result(const AccumuloProxy_renameTable_result&);
+  AccumuloProxy_renameTable_result& operator=(const AccumuloProxy_renameTable_result&);
   AccumuloProxy_renameTable_result() {
   }
 
-  virtual ~AccumuloProxy_renameTable_result() throw() {}
-
+  virtual ~AccumuloProxy_renameTable_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -5155,21 +4846,13 @@
 
   _AccumuloProxy_renameTable_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
-  void __set_ouch4(const TableExistsException& val) {
-    ouch4 = val;
-  }
+  void __set_ouch4(const TableExistsException& val);
 
   bool operator == (const AccumuloProxy_renameTable_result & rhs) const
   {
@@ -5196,18 +4879,17 @@
 
 typedef struct _AccumuloProxy_renameTable_presult__isset {
   _AccumuloProxy_renameTable_presult__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
-  bool ouch4;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
 } _AccumuloProxy_renameTable_presult__isset;
 
 class AccumuloProxy_renameTable_presult {
  public:
 
 
-  virtual ~AccumuloProxy_renameTable_presult() throw() {}
-
+  virtual ~AccumuloProxy_renameTable_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -5221,36 +4903,31 @@
 
 typedef struct _AccumuloProxy_setLocalityGroups_args__isset {
   _AccumuloProxy_setLocalityGroups_args__isset() : login(false), tableName(false), groups(false) {}
-  bool login;
-  bool tableName;
-  bool groups;
+  bool login :1;
+  bool tableName :1;
+  bool groups :1;
 } _AccumuloProxy_setLocalityGroups_args__isset;
 
 class AccumuloProxy_setLocalityGroups_args {
  public:
 
+  AccumuloProxy_setLocalityGroups_args(const AccumuloProxy_setLocalityGroups_args&);
+  AccumuloProxy_setLocalityGroups_args& operator=(const AccumuloProxy_setLocalityGroups_args&);
   AccumuloProxy_setLocalityGroups_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_setLocalityGroups_args() throw() {}
-
+  virtual ~AccumuloProxy_setLocalityGroups_args() throw();
   std::string login;
   std::string tableName;
   std::map<std::string, std::set<std::string> >  groups;
 
   _AccumuloProxy_setLocalityGroups_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_groups(const std::map<std::string, std::set<std::string> > & val) {
-    groups = val;
-  }
+  void __set_groups(const std::map<std::string, std::set<std::string> > & val);
 
   bool operator == (const AccumuloProxy_setLocalityGroups_args & rhs) const
   {
@@ -5278,8 +4955,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_setLocalityGroups_pargs() throw() {}
-
+  virtual ~AccumuloProxy_setLocalityGroups_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::map<std::string, std::set<std::string> > * groups;
@@ -5290,36 +4966,31 @@
 
 typedef struct _AccumuloProxy_setLocalityGroups_result__isset {
   _AccumuloProxy_setLocalityGroups_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_setLocalityGroups_result__isset;
 
 class AccumuloProxy_setLocalityGroups_result {
  public:
 
+  AccumuloProxy_setLocalityGroups_result(const AccumuloProxy_setLocalityGroups_result&);
+  AccumuloProxy_setLocalityGroups_result& operator=(const AccumuloProxy_setLocalityGroups_result&);
   AccumuloProxy_setLocalityGroups_result() {
   }
 
-  virtual ~AccumuloProxy_setLocalityGroups_result() throw() {}
-
+  virtual ~AccumuloProxy_setLocalityGroups_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_setLocalityGroups_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_setLocalityGroups_result & rhs) const
   {
@@ -5344,17 +5015,16 @@
 
 typedef struct _AccumuloProxy_setLocalityGroups_presult__isset {
   _AccumuloProxy_setLocalityGroups_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_setLocalityGroups_presult__isset;
 
 class AccumuloProxy_setLocalityGroups_presult {
  public:
 
 
-  virtual ~AccumuloProxy_setLocalityGroups_presult() throw() {}
-
+  virtual ~AccumuloProxy_setLocalityGroups_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -5367,20 +5037,21 @@
 
 typedef struct _AccumuloProxy_setTableProperty_args__isset {
   _AccumuloProxy_setTableProperty_args__isset() : login(false), tableName(false), property(false), value(false) {}
-  bool login;
-  bool tableName;
-  bool property;
-  bool value;
+  bool login :1;
+  bool tableName :1;
+  bool property :1;
+  bool value :1;
 } _AccumuloProxy_setTableProperty_args__isset;
 
 class AccumuloProxy_setTableProperty_args {
  public:
 
+  AccumuloProxy_setTableProperty_args(const AccumuloProxy_setTableProperty_args&);
+  AccumuloProxy_setTableProperty_args& operator=(const AccumuloProxy_setTableProperty_args&);
   AccumuloProxy_setTableProperty_args() : login(), tableName(), property(), value() {
   }
 
-  virtual ~AccumuloProxy_setTableProperty_args() throw() {}
-
+  virtual ~AccumuloProxy_setTableProperty_args() throw();
   std::string login;
   std::string tableName;
   std::string property;
@@ -5388,21 +5059,13 @@
 
   _AccumuloProxy_setTableProperty_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_property(const std::string& val) {
-    property = val;
-  }
+  void __set_property(const std::string& val);
 
-  void __set_value(const std::string& val) {
-    value = val;
-  }
+  void __set_value(const std::string& val);
 
   bool operator == (const AccumuloProxy_setTableProperty_args & rhs) const
   {
@@ -5432,8 +5095,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_setTableProperty_pargs() throw() {}
-
+  virtual ~AccumuloProxy_setTableProperty_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* property;
@@ -5445,36 +5107,31 @@
 
 typedef struct _AccumuloProxy_setTableProperty_result__isset {
   _AccumuloProxy_setTableProperty_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_setTableProperty_result__isset;
 
 class AccumuloProxy_setTableProperty_result {
  public:
 
+  AccumuloProxy_setTableProperty_result(const AccumuloProxy_setTableProperty_result&);
+  AccumuloProxy_setTableProperty_result& operator=(const AccumuloProxy_setTableProperty_result&);
   AccumuloProxy_setTableProperty_result() {
   }
 
-  virtual ~AccumuloProxy_setTableProperty_result() throw() {}
-
+  virtual ~AccumuloProxy_setTableProperty_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_setTableProperty_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_setTableProperty_result & rhs) const
   {
@@ -5499,17 +5156,16 @@
 
 typedef struct _AccumuloProxy_setTableProperty_presult__isset {
   _AccumuloProxy_setTableProperty_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_setTableProperty_presult__isset;
 
 class AccumuloProxy_setTableProperty_presult {
  public:
 
 
-  virtual ~AccumuloProxy_setTableProperty_presult() throw() {}
-
+  virtual ~AccumuloProxy_setTableProperty_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -5522,20 +5178,21 @@
 
 typedef struct _AccumuloProxy_splitRangeByTablets_args__isset {
   _AccumuloProxy_splitRangeByTablets_args__isset() : login(false), tableName(false), range(false), maxSplits(false) {}
-  bool login;
-  bool tableName;
-  bool range;
-  bool maxSplits;
+  bool login :1;
+  bool tableName :1;
+  bool range :1;
+  bool maxSplits :1;
 } _AccumuloProxy_splitRangeByTablets_args__isset;
 
 class AccumuloProxy_splitRangeByTablets_args {
  public:
 
+  AccumuloProxy_splitRangeByTablets_args(const AccumuloProxy_splitRangeByTablets_args&);
+  AccumuloProxy_splitRangeByTablets_args& operator=(const AccumuloProxy_splitRangeByTablets_args&);
   AccumuloProxy_splitRangeByTablets_args() : login(), tableName(), maxSplits(0) {
   }
 
-  virtual ~AccumuloProxy_splitRangeByTablets_args() throw() {}
-
+  virtual ~AccumuloProxy_splitRangeByTablets_args() throw();
   std::string login;
   std::string tableName;
   Range range;
@@ -5543,21 +5200,13 @@
 
   _AccumuloProxy_splitRangeByTablets_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_range(const Range& val) {
-    range = val;
-  }
+  void __set_range(const Range& val);
 
-  void __set_maxSplits(const int32_t val) {
-    maxSplits = val;
-  }
+  void __set_maxSplits(const int32_t val);
 
   bool operator == (const AccumuloProxy_splitRangeByTablets_args & rhs) const
   {
@@ -5587,8 +5236,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_splitRangeByTablets_pargs() throw() {}
-
+  virtual ~AccumuloProxy_splitRangeByTablets_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const Range* range;
@@ -5600,20 +5248,21 @@
 
 typedef struct _AccumuloProxy_splitRangeByTablets_result__isset {
   _AccumuloProxy_splitRangeByTablets_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_splitRangeByTablets_result__isset;
 
 class AccumuloProxy_splitRangeByTablets_result {
  public:
 
+  AccumuloProxy_splitRangeByTablets_result(const AccumuloProxy_splitRangeByTablets_result&);
+  AccumuloProxy_splitRangeByTablets_result& operator=(const AccumuloProxy_splitRangeByTablets_result&);
   AccumuloProxy_splitRangeByTablets_result() {
   }
 
-  virtual ~AccumuloProxy_splitRangeByTablets_result() throw() {}
-
+  virtual ~AccumuloProxy_splitRangeByTablets_result() throw();
   std::set<Range>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -5621,21 +5270,13 @@
 
   _AccumuloProxy_splitRangeByTablets_result__isset __isset;
 
-  void __set_success(const std::set<Range> & val) {
-    success = val;
-  }
+  void __set_success(const std::set<Range> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_splitRangeByTablets_result & rhs) const
   {
@@ -5662,18 +5303,17 @@
 
 typedef struct _AccumuloProxy_splitRangeByTablets_presult__isset {
   _AccumuloProxy_splitRangeByTablets_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_splitRangeByTablets_presult__isset;
 
 class AccumuloProxy_splitRangeByTablets_presult {
  public:
 
 
-  virtual ~AccumuloProxy_splitRangeByTablets_presult() throw() {}
-
+  virtual ~AccumuloProxy_splitRangeByTablets_presult() throw();
   std::set<Range> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -5687,30 +5327,27 @@
 
 typedef struct _AccumuloProxy_tableExists_args__isset {
   _AccumuloProxy_tableExists_args__isset() : login(false), tableName(false) {}
-  bool login;
-  bool tableName;
+  bool login :1;
+  bool tableName :1;
 } _AccumuloProxy_tableExists_args__isset;
 
 class AccumuloProxy_tableExists_args {
  public:
 
+  AccumuloProxy_tableExists_args(const AccumuloProxy_tableExists_args&);
+  AccumuloProxy_tableExists_args& operator=(const AccumuloProxy_tableExists_args&);
   AccumuloProxy_tableExists_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_tableExists_args() throw() {}
-
+  virtual ~AccumuloProxy_tableExists_args() throw();
   std::string login;
   std::string tableName;
 
   _AccumuloProxy_tableExists_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
   bool operator == (const AccumuloProxy_tableExists_args & rhs) const
   {
@@ -5736,8 +5373,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_tableExists_pargs() throw() {}
-
+  virtual ~AccumuloProxy_tableExists_pargs() throw();
   const std::string* login;
   const std::string* tableName;
 
@@ -5747,24 +5383,23 @@
 
 typedef struct _AccumuloProxy_tableExists_result__isset {
   _AccumuloProxy_tableExists_result__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_tableExists_result__isset;
 
 class AccumuloProxy_tableExists_result {
  public:
 
+  AccumuloProxy_tableExists_result(const AccumuloProxy_tableExists_result&);
+  AccumuloProxy_tableExists_result& operator=(const AccumuloProxy_tableExists_result&);
   AccumuloProxy_tableExists_result() : success(0) {
   }
 
-  virtual ~AccumuloProxy_tableExists_result() throw() {}
-
+  virtual ~AccumuloProxy_tableExists_result() throw();
   bool success;
 
   _AccumuloProxy_tableExists_result__isset __isset;
 
-  void __set_success(const bool val) {
-    success = val;
-  }
+  void __set_success(const bool val);
 
   bool operator == (const AccumuloProxy_tableExists_result & rhs) const
   {
@@ -5785,15 +5420,14 @@
 
 typedef struct _AccumuloProxy_tableExists_presult__isset {
   _AccumuloProxy_tableExists_presult__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_tableExists_presult__isset;
 
 class AccumuloProxy_tableExists_presult {
  public:
 
 
-  virtual ~AccumuloProxy_tableExists_presult() throw() {}
-
+  virtual ~AccumuloProxy_tableExists_presult() throw();
   bool* success;
 
   _AccumuloProxy_tableExists_presult__isset __isset;
@@ -5804,24 +5438,23 @@
 
 typedef struct _AccumuloProxy_tableIdMap_args__isset {
   _AccumuloProxy_tableIdMap_args__isset() : login(false) {}
-  bool login;
+  bool login :1;
 } _AccumuloProxy_tableIdMap_args__isset;
 
 class AccumuloProxy_tableIdMap_args {
  public:
 
+  AccumuloProxy_tableIdMap_args(const AccumuloProxy_tableIdMap_args&);
+  AccumuloProxy_tableIdMap_args& operator=(const AccumuloProxy_tableIdMap_args&);
   AccumuloProxy_tableIdMap_args() : login() {
   }
 
-  virtual ~AccumuloProxy_tableIdMap_args() throw() {}
-
+  virtual ~AccumuloProxy_tableIdMap_args() throw();
   std::string login;
 
   _AccumuloProxy_tableIdMap_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
   bool operator == (const AccumuloProxy_tableIdMap_args & rhs) const
   {
@@ -5845,8 +5478,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_tableIdMap_pargs() throw() {}
-
+  virtual ~AccumuloProxy_tableIdMap_pargs() throw();
   const std::string* login;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -5855,24 +5487,23 @@
 
 typedef struct _AccumuloProxy_tableIdMap_result__isset {
   _AccumuloProxy_tableIdMap_result__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_tableIdMap_result__isset;
 
 class AccumuloProxy_tableIdMap_result {
  public:
 
+  AccumuloProxy_tableIdMap_result(const AccumuloProxy_tableIdMap_result&);
+  AccumuloProxy_tableIdMap_result& operator=(const AccumuloProxy_tableIdMap_result&);
   AccumuloProxy_tableIdMap_result() {
   }
 
-  virtual ~AccumuloProxy_tableIdMap_result() throw() {}
-
+  virtual ~AccumuloProxy_tableIdMap_result() throw();
   std::map<std::string, std::string>  success;
 
   _AccumuloProxy_tableIdMap_result__isset __isset;
 
-  void __set_success(const std::map<std::string, std::string> & val) {
-    success = val;
-  }
+  void __set_success(const std::map<std::string, std::string> & val);
 
   bool operator == (const AccumuloProxy_tableIdMap_result & rhs) const
   {
@@ -5893,15 +5524,14 @@
 
 typedef struct _AccumuloProxy_tableIdMap_presult__isset {
   _AccumuloProxy_tableIdMap_presult__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_tableIdMap_presult__isset;
 
 class AccumuloProxy_tableIdMap_presult {
  public:
 
 
-  virtual ~AccumuloProxy_tableIdMap_presult() throw() {}
-
+  virtual ~AccumuloProxy_tableIdMap_presult() throw();
   std::map<std::string, std::string> * success;
 
   _AccumuloProxy_tableIdMap_presult__isset __isset;
@@ -5912,20 +5542,21 @@
 
 typedef struct _AccumuloProxy_testTableClassLoad_args__isset {
   _AccumuloProxy_testTableClassLoad_args__isset() : login(false), tableName(false), className(false), asTypeName(false) {}
-  bool login;
-  bool tableName;
-  bool className;
-  bool asTypeName;
+  bool login :1;
+  bool tableName :1;
+  bool className :1;
+  bool asTypeName :1;
 } _AccumuloProxy_testTableClassLoad_args__isset;
 
 class AccumuloProxy_testTableClassLoad_args {
  public:
 
+  AccumuloProxy_testTableClassLoad_args(const AccumuloProxy_testTableClassLoad_args&);
+  AccumuloProxy_testTableClassLoad_args& operator=(const AccumuloProxy_testTableClassLoad_args&);
   AccumuloProxy_testTableClassLoad_args() : login(), tableName(), className(), asTypeName() {
   }
 
-  virtual ~AccumuloProxy_testTableClassLoad_args() throw() {}
-
+  virtual ~AccumuloProxy_testTableClassLoad_args() throw();
   std::string login;
   std::string tableName;
   std::string className;
@@ -5933,21 +5564,13 @@
 
   _AccumuloProxy_testTableClassLoad_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_className(const std::string& val) {
-    className = val;
-  }
+  void __set_className(const std::string& val);
 
-  void __set_asTypeName(const std::string& val) {
-    asTypeName = val;
-  }
+  void __set_asTypeName(const std::string& val);
 
   bool operator == (const AccumuloProxy_testTableClassLoad_args & rhs) const
   {
@@ -5977,8 +5600,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_testTableClassLoad_pargs() throw() {}
-
+  virtual ~AccumuloProxy_testTableClassLoad_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* className;
@@ -5990,20 +5612,21 @@
 
 typedef struct _AccumuloProxy_testTableClassLoad_result__isset {
   _AccumuloProxy_testTableClassLoad_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_testTableClassLoad_result__isset;
 
 class AccumuloProxy_testTableClassLoad_result {
  public:
 
+  AccumuloProxy_testTableClassLoad_result(const AccumuloProxy_testTableClassLoad_result&);
+  AccumuloProxy_testTableClassLoad_result& operator=(const AccumuloProxy_testTableClassLoad_result&);
   AccumuloProxy_testTableClassLoad_result() : success(0) {
   }
 
-  virtual ~AccumuloProxy_testTableClassLoad_result() throw() {}
-
+  virtual ~AccumuloProxy_testTableClassLoad_result() throw();
   bool success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -6011,21 +5634,13 @@
 
   _AccumuloProxy_testTableClassLoad_result__isset __isset;
 
-  void __set_success(const bool val) {
-    success = val;
-  }
+  void __set_success(const bool val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_testTableClassLoad_result & rhs) const
   {
@@ -6052,18 +5667,17 @@
 
 typedef struct _AccumuloProxy_testTableClassLoad_presult__isset {
   _AccumuloProxy_testTableClassLoad_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_testTableClassLoad_presult__isset;
 
 class AccumuloProxy_testTableClassLoad_presult {
  public:
 
 
-  virtual ~AccumuloProxy_testTableClassLoad_presult() throw() {}
-
+  virtual ~AccumuloProxy_testTableClassLoad_presult() throw();
   bool* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -6077,30 +5691,27 @@
 
 typedef struct _AccumuloProxy_pingTabletServer_args__isset {
   _AccumuloProxy_pingTabletServer_args__isset() : login(false), tserver(false) {}
-  bool login;
-  bool tserver;
+  bool login :1;
+  bool tserver :1;
 } _AccumuloProxy_pingTabletServer_args__isset;
 
 class AccumuloProxy_pingTabletServer_args {
  public:
 
+  AccumuloProxy_pingTabletServer_args(const AccumuloProxy_pingTabletServer_args&);
+  AccumuloProxy_pingTabletServer_args& operator=(const AccumuloProxy_pingTabletServer_args&);
   AccumuloProxy_pingTabletServer_args() : login(), tserver() {
   }
 
-  virtual ~AccumuloProxy_pingTabletServer_args() throw() {}
-
+  virtual ~AccumuloProxy_pingTabletServer_args() throw();
   std::string login;
   std::string tserver;
 
   _AccumuloProxy_pingTabletServer_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tserver(const std::string& val) {
-    tserver = val;
-  }
+  void __set_tserver(const std::string& val);
 
   bool operator == (const AccumuloProxy_pingTabletServer_args & rhs) const
   {
@@ -6126,8 +5737,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_pingTabletServer_pargs() throw() {}
-
+  virtual ~AccumuloProxy_pingTabletServer_pargs() throw();
   const std::string* login;
   const std::string* tserver;
 
@@ -6137,30 +5747,27 @@
 
 typedef struct _AccumuloProxy_pingTabletServer_result__isset {
   _AccumuloProxy_pingTabletServer_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_pingTabletServer_result__isset;
 
 class AccumuloProxy_pingTabletServer_result {
  public:
 
+  AccumuloProxy_pingTabletServer_result(const AccumuloProxy_pingTabletServer_result&);
+  AccumuloProxy_pingTabletServer_result& operator=(const AccumuloProxy_pingTabletServer_result&);
   AccumuloProxy_pingTabletServer_result() {
   }
 
-  virtual ~AccumuloProxy_pingTabletServer_result() throw() {}
-
+  virtual ~AccumuloProxy_pingTabletServer_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_pingTabletServer_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_pingTabletServer_result & rhs) const
   {
@@ -6183,16 +5790,15 @@
 
 typedef struct _AccumuloProxy_pingTabletServer_presult__isset {
   _AccumuloProxy_pingTabletServer_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_pingTabletServer_presult__isset;
 
 class AccumuloProxy_pingTabletServer_presult {
  public:
 
 
-  virtual ~AccumuloProxy_pingTabletServer_presult() throw() {}
-
+  virtual ~AccumuloProxy_pingTabletServer_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
@@ -6204,30 +5810,27 @@
 
 typedef struct _AccumuloProxy_getActiveScans_args__isset {
   _AccumuloProxy_getActiveScans_args__isset() : login(false), tserver(false) {}
-  bool login;
-  bool tserver;
+  bool login :1;
+  bool tserver :1;
 } _AccumuloProxy_getActiveScans_args__isset;
 
 class AccumuloProxy_getActiveScans_args {
  public:
 
+  AccumuloProxy_getActiveScans_args(const AccumuloProxy_getActiveScans_args&);
+  AccumuloProxy_getActiveScans_args& operator=(const AccumuloProxy_getActiveScans_args&);
   AccumuloProxy_getActiveScans_args() : login(), tserver() {
   }
 
-  virtual ~AccumuloProxy_getActiveScans_args() throw() {}
-
+  virtual ~AccumuloProxy_getActiveScans_args() throw();
   std::string login;
   std::string tserver;
 
   _AccumuloProxy_getActiveScans_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tserver(const std::string& val) {
-    tserver = val;
-  }
+  void __set_tserver(const std::string& val);
 
   bool operator == (const AccumuloProxy_getActiveScans_args & rhs) const
   {
@@ -6253,8 +5856,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getActiveScans_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getActiveScans_pargs() throw();
   const std::string* login;
   const std::string* tserver;
 
@@ -6264,36 +5866,31 @@
 
 typedef struct _AccumuloProxy_getActiveScans_result__isset {
   _AccumuloProxy_getActiveScans_result__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_getActiveScans_result__isset;
 
 class AccumuloProxy_getActiveScans_result {
  public:
 
+  AccumuloProxy_getActiveScans_result(const AccumuloProxy_getActiveScans_result&);
+  AccumuloProxy_getActiveScans_result& operator=(const AccumuloProxy_getActiveScans_result&);
   AccumuloProxy_getActiveScans_result() {
   }
 
-  virtual ~AccumuloProxy_getActiveScans_result() throw() {}
-
+  virtual ~AccumuloProxy_getActiveScans_result() throw();
   std::vector<ActiveScan>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_getActiveScans_result__isset __isset;
 
-  void __set_success(const std::vector<ActiveScan> & val) {
-    success = val;
-  }
+  void __set_success(const std::vector<ActiveScan> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_getActiveScans_result & rhs) const
   {
@@ -6318,17 +5915,16 @@
 
 typedef struct _AccumuloProxy_getActiveScans_presult__isset {
   _AccumuloProxy_getActiveScans_presult__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_getActiveScans_presult__isset;
 
 class AccumuloProxy_getActiveScans_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getActiveScans_presult() throw() {}
-
+  virtual ~AccumuloProxy_getActiveScans_presult() throw();
   std::vector<ActiveScan> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -6341,30 +5937,27 @@
 
 typedef struct _AccumuloProxy_getActiveCompactions_args__isset {
   _AccumuloProxy_getActiveCompactions_args__isset() : login(false), tserver(false) {}
-  bool login;
-  bool tserver;
+  bool login :1;
+  bool tserver :1;
 } _AccumuloProxy_getActiveCompactions_args__isset;
 
 class AccumuloProxy_getActiveCompactions_args {
  public:
 
+  AccumuloProxy_getActiveCompactions_args(const AccumuloProxy_getActiveCompactions_args&);
+  AccumuloProxy_getActiveCompactions_args& operator=(const AccumuloProxy_getActiveCompactions_args&);
   AccumuloProxy_getActiveCompactions_args() : login(), tserver() {
   }
 
-  virtual ~AccumuloProxy_getActiveCompactions_args() throw() {}
-
+  virtual ~AccumuloProxy_getActiveCompactions_args() throw();
   std::string login;
   std::string tserver;
 
   _AccumuloProxy_getActiveCompactions_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tserver(const std::string& val) {
-    tserver = val;
-  }
+  void __set_tserver(const std::string& val);
 
   bool operator == (const AccumuloProxy_getActiveCompactions_args & rhs) const
   {
@@ -6390,8 +5983,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getActiveCompactions_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getActiveCompactions_pargs() throw();
   const std::string* login;
   const std::string* tserver;
 
@@ -6401,36 +5993,31 @@
 
 typedef struct _AccumuloProxy_getActiveCompactions_result__isset {
   _AccumuloProxy_getActiveCompactions_result__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_getActiveCompactions_result__isset;
 
 class AccumuloProxy_getActiveCompactions_result {
  public:
 
+  AccumuloProxy_getActiveCompactions_result(const AccumuloProxy_getActiveCompactions_result&);
+  AccumuloProxy_getActiveCompactions_result& operator=(const AccumuloProxy_getActiveCompactions_result&);
   AccumuloProxy_getActiveCompactions_result() {
   }
 
-  virtual ~AccumuloProxy_getActiveCompactions_result() throw() {}
-
+  virtual ~AccumuloProxy_getActiveCompactions_result() throw();
   std::vector<ActiveCompaction>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_getActiveCompactions_result__isset __isset;
 
-  void __set_success(const std::vector<ActiveCompaction> & val) {
-    success = val;
-  }
+  void __set_success(const std::vector<ActiveCompaction> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_getActiveCompactions_result & rhs) const
   {
@@ -6455,17 +6042,16 @@
 
 typedef struct _AccumuloProxy_getActiveCompactions_presult__isset {
   _AccumuloProxy_getActiveCompactions_presult__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_getActiveCompactions_presult__isset;
 
 class AccumuloProxy_getActiveCompactions_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getActiveCompactions_presult() throw() {}
-
+  virtual ~AccumuloProxy_getActiveCompactions_presult() throw();
   std::vector<ActiveCompaction> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -6478,24 +6064,23 @@
 
 typedef struct _AccumuloProxy_getSiteConfiguration_args__isset {
   _AccumuloProxy_getSiteConfiguration_args__isset() : login(false) {}
-  bool login;
+  bool login :1;
 } _AccumuloProxy_getSiteConfiguration_args__isset;
 
 class AccumuloProxy_getSiteConfiguration_args {
  public:
 
+  AccumuloProxy_getSiteConfiguration_args(const AccumuloProxy_getSiteConfiguration_args&);
+  AccumuloProxy_getSiteConfiguration_args& operator=(const AccumuloProxy_getSiteConfiguration_args&);
   AccumuloProxy_getSiteConfiguration_args() : login() {
   }
 
-  virtual ~AccumuloProxy_getSiteConfiguration_args() throw() {}
-
+  virtual ~AccumuloProxy_getSiteConfiguration_args() throw();
   std::string login;
 
   _AccumuloProxy_getSiteConfiguration_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
   bool operator == (const AccumuloProxy_getSiteConfiguration_args & rhs) const
   {
@@ -6519,8 +6104,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getSiteConfiguration_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getSiteConfiguration_pargs() throw();
   const std::string* login;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -6529,36 +6113,31 @@
 
 typedef struct _AccumuloProxy_getSiteConfiguration_result__isset {
   _AccumuloProxy_getSiteConfiguration_result__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_getSiteConfiguration_result__isset;
 
 class AccumuloProxy_getSiteConfiguration_result {
  public:
 
+  AccumuloProxy_getSiteConfiguration_result(const AccumuloProxy_getSiteConfiguration_result&);
+  AccumuloProxy_getSiteConfiguration_result& operator=(const AccumuloProxy_getSiteConfiguration_result&);
   AccumuloProxy_getSiteConfiguration_result() {
   }
 
-  virtual ~AccumuloProxy_getSiteConfiguration_result() throw() {}
-
+  virtual ~AccumuloProxy_getSiteConfiguration_result() throw();
   std::map<std::string, std::string>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_getSiteConfiguration_result__isset __isset;
 
-  void __set_success(const std::map<std::string, std::string> & val) {
-    success = val;
-  }
+  void __set_success(const std::map<std::string, std::string> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_getSiteConfiguration_result & rhs) const
   {
@@ -6583,17 +6162,16 @@
 
 typedef struct _AccumuloProxy_getSiteConfiguration_presult__isset {
   _AccumuloProxy_getSiteConfiguration_presult__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_getSiteConfiguration_presult__isset;
 
 class AccumuloProxy_getSiteConfiguration_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getSiteConfiguration_presult() throw() {}
-
+  virtual ~AccumuloProxy_getSiteConfiguration_presult() throw();
   std::map<std::string, std::string> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -6606,24 +6184,23 @@
 
 typedef struct _AccumuloProxy_getSystemConfiguration_args__isset {
   _AccumuloProxy_getSystemConfiguration_args__isset() : login(false) {}
-  bool login;
+  bool login :1;
 } _AccumuloProxy_getSystemConfiguration_args__isset;
 
 class AccumuloProxy_getSystemConfiguration_args {
  public:
 
+  AccumuloProxy_getSystemConfiguration_args(const AccumuloProxy_getSystemConfiguration_args&);
+  AccumuloProxy_getSystemConfiguration_args& operator=(const AccumuloProxy_getSystemConfiguration_args&);
   AccumuloProxy_getSystemConfiguration_args() : login() {
   }
 
-  virtual ~AccumuloProxy_getSystemConfiguration_args() throw() {}
-
+  virtual ~AccumuloProxy_getSystemConfiguration_args() throw();
   std::string login;
 
   _AccumuloProxy_getSystemConfiguration_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
   bool operator == (const AccumuloProxy_getSystemConfiguration_args & rhs) const
   {
@@ -6647,8 +6224,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getSystemConfiguration_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getSystemConfiguration_pargs() throw();
   const std::string* login;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -6657,36 +6233,31 @@
 
 typedef struct _AccumuloProxy_getSystemConfiguration_result__isset {
   _AccumuloProxy_getSystemConfiguration_result__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_getSystemConfiguration_result__isset;
 
 class AccumuloProxy_getSystemConfiguration_result {
  public:
 
+  AccumuloProxy_getSystemConfiguration_result(const AccumuloProxy_getSystemConfiguration_result&);
+  AccumuloProxy_getSystemConfiguration_result& operator=(const AccumuloProxy_getSystemConfiguration_result&);
   AccumuloProxy_getSystemConfiguration_result() {
   }
 
-  virtual ~AccumuloProxy_getSystemConfiguration_result() throw() {}
-
+  virtual ~AccumuloProxy_getSystemConfiguration_result() throw();
   std::map<std::string, std::string>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_getSystemConfiguration_result__isset __isset;
 
-  void __set_success(const std::map<std::string, std::string> & val) {
-    success = val;
-  }
+  void __set_success(const std::map<std::string, std::string> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_getSystemConfiguration_result & rhs) const
   {
@@ -6711,17 +6282,16 @@
 
 typedef struct _AccumuloProxy_getSystemConfiguration_presult__isset {
   _AccumuloProxy_getSystemConfiguration_presult__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_getSystemConfiguration_presult__isset;
 
 class AccumuloProxy_getSystemConfiguration_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getSystemConfiguration_presult() throw() {}
-
+  virtual ~AccumuloProxy_getSystemConfiguration_presult() throw();
   std::map<std::string, std::string> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -6734,24 +6304,23 @@
 
 typedef struct _AccumuloProxy_getTabletServers_args__isset {
   _AccumuloProxy_getTabletServers_args__isset() : login(false) {}
-  bool login;
+  bool login :1;
 } _AccumuloProxy_getTabletServers_args__isset;
 
 class AccumuloProxy_getTabletServers_args {
  public:
 
+  AccumuloProxy_getTabletServers_args(const AccumuloProxy_getTabletServers_args&);
+  AccumuloProxy_getTabletServers_args& operator=(const AccumuloProxy_getTabletServers_args&);
   AccumuloProxy_getTabletServers_args() : login() {
   }
 
-  virtual ~AccumuloProxy_getTabletServers_args() throw() {}
-
+  virtual ~AccumuloProxy_getTabletServers_args() throw();
   std::string login;
 
   _AccumuloProxy_getTabletServers_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
   bool operator == (const AccumuloProxy_getTabletServers_args & rhs) const
   {
@@ -6775,8 +6344,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getTabletServers_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getTabletServers_pargs() throw();
   const std::string* login;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -6785,24 +6353,23 @@
 
 typedef struct _AccumuloProxy_getTabletServers_result__isset {
   _AccumuloProxy_getTabletServers_result__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_getTabletServers_result__isset;
 
 class AccumuloProxy_getTabletServers_result {
  public:
 
+  AccumuloProxy_getTabletServers_result(const AccumuloProxy_getTabletServers_result&);
+  AccumuloProxy_getTabletServers_result& operator=(const AccumuloProxy_getTabletServers_result&);
   AccumuloProxy_getTabletServers_result() {
   }
 
-  virtual ~AccumuloProxy_getTabletServers_result() throw() {}
-
+  virtual ~AccumuloProxy_getTabletServers_result() throw();
   std::vector<std::string>  success;
 
   _AccumuloProxy_getTabletServers_result__isset __isset;
 
-  void __set_success(const std::vector<std::string> & val) {
-    success = val;
-  }
+  void __set_success(const std::vector<std::string> & val);
 
   bool operator == (const AccumuloProxy_getTabletServers_result & rhs) const
   {
@@ -6823,15 +6390,14 @@
 
 typedef struct _AccumuloProxy_getTabletServers_presult__isset {
   _AccumuloProxy_getTabletServers_presult__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_getTabletServers_presult__isset;
 
 class AccumuloProxy_getTabletServers_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getTabletServers_presult() throw() {}
-
+  virtual ~AccumuloProxy_getTabletServers_presult() throw();
   std::vector<std::string> * success;
 
   _AccumuloProxy_getTabletServers_presult__isset __isset;
@@ -6842,30 +6408,27 @@
 
 typedef struct _AccumuloProxy_removeProperty_args__isset {
   _AccumuloProxy_removeProperty_args__isset() : login(false), property(false) {}
-  bool login;
-  bool property;
+  bool login :1;
+  bool property :1;
 } _AccumuloProxy_removeProperty_args__isset;
 
 class AccumuloProxy_removeProperty_args {
  public:
 
+  AccumuloProxy_removeProperty_args(const AccumuloProxy_removeProperty_args&);
+  AccumuloProxy_removeProperty_args& operator=(const AccumuloProxy_removeProperty_args&);
   AccumuloProxy_removeProperty_args() : login(), property() {
   }
 
-  virtual ~AccumuloProxy_removeProperty_args() throw() {}
-
+  virtual ~AccumuloProxy_removeProperty_args() throw();
   std::string login;
   std::string property;
 
   _AccumuloProxy_removeProperty_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_property(const std::string& val) {
-    property = val;
-  }
+  void __set_property(const std::string& val);
 
   bool operator == (const AccumuloProxy_removeProperty_args & rhs) const
   {
@@ -6891,8 +6454,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_removeProperty_pargs() throw() {}
-
+  virtual ~AccumuloProxy_removeProperty_pargs() throw();
   const std::string* login;
   const std::string* property;
 
@@ -6902,30 +6464,27 @@
 
 typedef struct _AccumuloProxy_removeProperty_result__isset {
   _AccumuloProxy_removeProperty_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_removeProperty_result__isset;
 
 class AccumuloProxy_removeProperty_result {
  public:
 
+  AccumuloProxy_removeProperty_result(const AccumuloProxy_removeProperty_result&);
+  AccumuloProxy_removeProperty_result& operator=(const AccumuloProxy_removeProperty_result&);
   AccumuloProxy_removeProperty_result() {
   }
 
-  virtual ~AccumuloProxy_removeProperty_result() throw() {}
-
+  virtual ~AccumuloProxy_removeProperty_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_removeProperty_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_removeProperty_result & rhs) const
   {
@@ -6948,16 +6507,15 @@
 
 typedef struct _AccumuloProxy_removeProperty_presult__isset {
   _AccumuloProxy_removeProperty_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_removeProperty_presult__isset;
 
 class AccumuloProxy_removeProperty_presult {
  public:
 
 
-  virtual ~AccumuloProxy_removeProperty_presult() throw() {}
-
+  virtual ~AccumuloProxy_removeProperty_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
@@ -6969,36 +6527,31 @@
 
 typedef struct _AccumuloProxy_setProperty_args__isset {
   _AccumuloProxy_setProperty_args__isset() : login(false), property(false), value(false) {}
-  bool login;
-  bool property;
-  bool value;
+  bool login :1;
+  bool property :1;
+  bool value :1;
 } _AccumuloProxy_setProperty_args__isset;
 
 class AccumuloProxy_setProperty_args {
  public:
 
+  AccumuloProxy_setProperty_args(const AccumuloProxy_setProperty_args&);
+  AccumuloProxy_setProperty_args& operator=(const AccumuloProxy_setProperty_args&);
   AccumuloProxy_setProperty_args() : login(), property(), value() {
   }
 
-  virtual ~AccumuloProxy_setProperty_args() throw() {}
-
+  virtual ~AccumuloProxy_setProperty_args() throw();
   std::string login;
   std::string property;
   std::string value;
 
   _AccumuloProxy_setProperty_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_property(const std::string& val) {
-    property = val;
-  }
+  void __set_property(const std::string& val);
 
-  void __set_value(const std::string& val) {
-    value = val;
-  }
+  void __set_value(const std::string& val);
 
   bool operator == (const AccumuloProxy_setProperty_args & rhs) const
   {
@@ -7026,8 +6579,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_setProperty_pargs() throw() {}
-
+  virtual ~AccumuloProxy_setProperty_pargs() throw();
   const std::string* login;
   const std::string* property;
   const std::string* value;
@@ -7038,30 +6590,27 @@
 
 typedef struct _AccumuloProxy_setProperty_result__isset {
   _AccumuloProxy_setProperty_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_setProperty_result__isset;
 
 class AccumuloProxy_setProperty_result {
  public:
 
+  AccumuloProxy_setProperty_result(const AccumuloProxy_setProperty_result&);
+  AccumuloProxy_setProperty_result& operator=(const AccumuloProxy_setProperty_result&);
   AccumuloProxy_setProperty_result() {
   }
 
-  virtual ~AccumuloProxy_setProperty_result() throw() {}
-
+  virtual ~AccumuloProxy_setProperty_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_setProperty_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_setProperty_result & rhs) const
   {
@@ -7084,16 +6633,15 @@
 
 typedef struct _AccumuloProxy_setProperty_presult__isset {
   _AccumuloProxy_setProperty_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_setProperty_presult__isset;
 
 class AccumuloProxy_setProperty_presult {
  public:
 
 
-  virtual ~AccumuloProxy_setProperty_presult() throw() {}
-
+  virtual ~AccumuloProxy_setProperty_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
@@ -7105,36 +6653,31 @@
 
 typedef struct _AccumuloProxy_testClassLoad_args__isset {
   _AccumuloProxy_testClassLoad_args__isset() : login(false), className(false), asTypeName(false) {}
-  bool login;
-  bool className;
-  bool asTypeName;
+  bool login :1;
+  bool className :1;
+  bool asTypeName :1;
 } _AccumuloProxy_testClassLoad_args__isset;
 
 class AccumuloProxy_testClassLoad_args {
  public:
 
+  AccumuloProxy_testClassLoad_args(const AccumuloProxy_testClassLoad_args&);
+  AccumuloProxy_testClassLoad_args& operator=(const AccumuloProxy_testClassLoad_args&);
   AccumuloProxy_testClassLoad_args() : login(), className(), asTypeName() {
   }
 
-  virtual ~AccumuloProxy_testClassLoad_args() throw() {}
-
+  virtual ~AccumuloProxy_testClassLoad_args() throw();
   std::string login;
   std::string className;
   std::string asTypeName;
 
   _AccumuloProxy_testClassLoad_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_className(const std::string& val) {
-    className = val;
-  }
+  void __set_className(const std::string& val);
 
-  void __set_asTypeName(const std::string& val) {
-    asTypeName = val;
-  }
+  void __set_asTypeName(const std::string& val);
 
   bool operator == (const AccumuloProxy_testClassLoad_args & rhs) const
   {
@@ -7162,8 +6705,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_testClassLoad_pargs() throw() {}
-
+  virtual ~AccumuloProxy_testClassLoad_pargs() throw();
   const std::string* login;
   const std::string* className;
   const std::string* asTypeName;
@@ -7174,36 +6716,31 @@
 
 typedef struct _AccumuloProxy_testClassLoad_result__isset {
   _AccumuloProxy_testClassLoad_result__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_testClassLoad_result__isset;
 
 class AccumuloProxy_testClassLoad_result {
  public:
 
+  AccumuloProxy_testClassLoad_result(const AccumuloProxy_testClassLoad_result&);
+  AccumuloProxy_testClassLoad_result& operator=(const AccumuloProxy_testClassLoad_result&);
   AccumuloProxy_testClassLoad_result() : success(0) {
   }
 
-  virtual ~AccumuloProxy_testClassLoad_result() throw() {}
-
+  virtual ~AccumuloProxy_testClassLoad_result() throw();
   bool success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_testClassLoad_result__isset __isset;
 
-  void __set_success(const bool val) {
-    success = val;
-  }
+  void __set_success(const bool val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_testClassLoad_result & rhs) const
   {
@@ -7228,17 +6765,16 @@
 
 typedef struct _AccumuloProxy_testClassLoad_presult__isset {
   _AccumuloProxy_testClassLoad_presult__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_testClassLoad_presult__isset;
 
 class AccumuloProxy_testClassLoad_presult {
  public:
 
 
-  virtual ~AccumuloProxy_testClassLoad_presult() throw() {}
-
+  virtual ~AccumuloProxy_testClassLoad_presult() throw();
   bool* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -7251,36 +6787,31 @@
 
 typedef struct _AccumuloProxy_authenticateUser_args__isset {
   _AccumuloProxy_authenticateUser_args__isset() : login(false), user(false), properties(false) {}
-  bool login;
-  bool user;
-  bool properties;
+  bool login :1;
+  bool user :1;
+  bool properties :1;
 } _AccumuloProxy_authenticateUser_args__isset;
 
 class AccumuloProxy_authenticateUser_args {
  public:
 
+  AccumuloProxy_authenticateUser_args(const AccumuloProxy_authenticateUser_args&);
+  AccumuloProxy_authenticateUser_args& operator=(const AccumuloProxy_authenticateUser_args&);
   AccumuloProxy_authenticateUser_args() : login(), user() {
   }
 
-  virtual ~AccumuloProxy_authenticateUser_args() throw() {}
-
+  virtual ~AccumuloProxy_authenticateUser_args() throw();
   std::string login;
   std::string user;
   std::map<std::string, std::string>  properties;
 
   _AccumuloProxy_authenticateUser_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_properties(const std::map<std::string, std::string> & val) {
-    properties = val;
-  }
+  void __set_properties(const std::map<std::string, std::string> & val);
 
   bool operator == (const AccumuloProxy_authenticateUser_args & rhs) const
   {
@@ -7308,8 +6839,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_authenticateUser_pargs() throw() {}
-
+  virtual ~AccumuloProxy_authenticateUser_pargs() throw();
   const std::string* login;
   const std::string* user;
   const std::map<std::string, std::string> * properties;
@@ -7320,36 +6850,31 @@
 
 typedef struct _AccumuloProxy_authenticateUser_result__isset {
   _AccumuloProxy_authenticateUser_result__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_authenticateUser_result__isset;
 
 class AccumuloProxy_authenticateUser_result {
  public:
 
+  AccumuloProxy_authenticateUser_result(const AccumuloProxy_authenticateUser_result&);
+  AccumuloProxy_authenticateUser_result& operator=(const AccumuloProxy_authenticateUser_result&);
   AccumuloProxy_authenticateUser_result() : success(0) {
   }
 
-  virtual ~AccumuloProxy_authenticateUser_result() throw() {}
-
+  virtual ~AccumuloProxy_authenticateUser_result() throw();
   bool success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_authenticateUser_result__isset __isset;
 
-  void __set_success(const bool val) {
-    success = val;
-  }
+  void __set_success(const bool val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_authenticateUser_result & rhs) const
   {
@@ -7374,17 +6899,16 @@
 
 typedef struct _AccumuloProxy_authenticateUser_presult__isset {
   _AccumuloProxy_authenticateUser_presult__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_authenticateUser_presult__isset;
 
 class AccumuloProxy_authenticateUser_presult {
  public:
 
 
-  virtual ~AccumuloProxy_authenticateUser_presult() throw() {}
-
+  virtual ~AccumuloProxy_authenticateUser_presult() throw();
   bool* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -7397,36 +6921,31 @@
 
 typedef struct _AccumuloProxy_changeUserAuthorizations_args__isset {
   _AccumuloProxy_changeUserAuthorizations_args__isset() : login(false), user(false), authorizations(false) {}
-  bool login;
-  bool user;
-  bool authorizations;
+  bool login :1;
+  bool user :1;
+  bool authorizations :1;
 } _AccumuloProxy_changeUserAuthorizations_args__isset;
 
 class AccumuloProxy_changeUserAuthorizations_args {
  public:
 
+  AccumuloProxy_changeUserAuthorizations_args(const AccumuloProxy_changeUserAuthorizations_args&);
+  AccumuloProxy_changeUserAuthorizations_args& operator=(const AccumuloProxy_changeUserAuthorizations_args&);
   AccumuloProxy_changeUserAuthorizations_args() : login(), user() {
   }
 
-  virtual ~AccumuloProxy_changeUserAuthorizations_args() throw() {}
-
+  virtual ~AccumuloProxy_changeUserAuthorizations_args() throw();
   std::string login;
   std::string user;
   std::set<std::string>  authorizations;
 
   _AccumuloProxy_changeUserAuthorizations_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_authorizations(const std::set<std::string> & val) {
-    authorizations = val;
-  }
+  void __set_authorizations(const std::set<std::string> & val);
 
   bool operator == (const AccumuloProxy_changeUserAuthorizations_args & rhs) const
   {
@@ -7454,8 +6973,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_changeUserAuthorizations_pargs() throw() {}
-
+  virtual ~AccumuloProxy_changeUserAuthorizations_pargs() throw();
   const std::string* login;
   const std::string* user;
   const std::set<std::string> * authorizations;
@@ -7466,30 +6984,27 @@
 
 typedef struct _AccumuloProxy_changeUserAuthorizations_result__isset {
   _AccumuloProxy_changeUserAuthorizations_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_changeUserAuthorizations_result__isset;
 
 class AccumuloProxy_changeUserAuthorizations_result {
  public:
 
+  AccumuloProxy_changeUserAuthorizations_result(const AccumuloProxy_changeUserAuthorizations_result&);
+  AccumuloProxy_changeUserAuthorizations_result& operator=(const AccumuloProxy_changeUserAuthorizations_result&);
   AccumuloProxy_changeUserAuthorizations_result() {
   }
 
-  virtual ~AccumuloProxy_changeUserAuthorizations_result() throw() {}
-
+  virtual ~AccumuloProxy_changeUserAuthorizations_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_changeUserAuthorizations_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_changeUserAuthorizations_result & rhs) const
   {
@@ -7512,16 +7027,15 @@
 
 typedef struct _AccumuloProxy_changeUserAuthorizations_presult__isset {
   _AccumuloProxy_changeUserAuthorizations_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_changeUserAuthorizations_presult__isset;
 
 class AccumuloProxy_changeUserAuthorizations_presult {
  public:
 
 
-  virtual ~AccumuloProxy_changeUserAuthorizations_presult() throw() {}
-
+  virtual ~AccumuloProxy_changeUserAuthorizations_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
@@ -7533,36 +7047,31 @@
 
 typedef struct _AccumuloProxy_changeLocalUserPassword_args__isset {
   _AccumuloProxy_changeLocalUserPassword_args__isset() : login(false), user(false), password(false) {}
-  bool login;
-  bool user;
-  bool password;
+  bool login :1;
+  bool user :1;
+  bool password :1;
 } _AccumuloProxy_changeLocalUserPassword_args__isset;
 
 class AccumuloProxy_changeLocalUserPassword_args {
  public:
 
+  AccumuloProxy_changeLocalUserPassword_args(const AccumuloProxy_changeLocalUserPassword_args&);
+  AccumuloProxy_changeLocalUserPassword_args& operator=(const AccumuloProxy_changeLocalUserPassword_args&);
   AccumuloProxy_changeLocalUserPassword_args() : login(), user(), password() {
   }
 
-  virtual ~AccumuloProxy_changeLocalUserPassword_args() throw() {}
-
+  virtual ~AccumuloProxy_changeLocalUserPassword_args() throw();
   std::string login;
   std::string user;
   std::string password;
 
   _AccumuloProxy_changeLocalUserPassword_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_password(const std::string& val) {
-    password = val;
-  }
+  void __set_password(const std::string& val);
 
   bool operator == (const AccumuloProxy_changeLocalUserPassword_args & rhs) const
   {
@@ -7590,8 +7099,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_changeLocalUserPassword_pargs() throw() {}
-
+  virtual ~AccumuloProxy_changeLocalUserPassword_pargs() throw();
   const std::string* login;
   const std::string* user;
   const std::string* password;
@@ -7602,30 +7110,27 @@
 
 typedef struct _AccumuloProxy_changeLocalUserPassword_result__isset {
   _AccumuloProxy_changeLocalUserPassword_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_changeLocalUserPassword_result__isset;
 
 class AccumuloProxy_changeLocalUserPassword_result {
  public:
 
+  AccumuloProxy_changeLocalUserPassword_result(const AccumuloProxy_changeLocalUserPassword_result&);
+  AccumuloProxy_changeLocalUserPassword_result& operator=(const AccumuloProxy_changeLocalUserPassword_result&);
   AccumuloProxy_changeLocalUserPassword_result() {
   }
 
-  virtual ~AccumuloProxy_changeLocalUserPassword_result() throw() {}
-
+  virtual ~AccumuloProxy_changeLocalUserPassword_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_changeLocalUserPassword_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_changeLocalUserPassword_result & rhs) const
   {
@@ -7648,16 +7153,15 @@
 
 typedef struct _AccumuloProxy_changeLocalUserPassword_presult__isset {
   _AccumuloProxy_changeLocalUserPassword_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_changeLocalUserPassword_presult__isset;
 
 class AccumuloProxy_changeLocalUserPassword_presult {
  public:
 
 
-  virtual ~AccumuloProxy_changeLocalUserPassword_presult() throw() {}
-
+  virtual ~AccumuloProxy_changeLocalUserPassword_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
@@ -7669,36 +7173,31 @@
 
 typedef struct _AccumuloProxy_createLocalUser_args__isset {
   _AccumuloProxy_createLocalUser_args__isset() : login(false), user(false), password(false) {}
-  bool login;
-  bool user;
-  bool password;
+  bool login :1;
+  bool user :1;
+  bool password :1;
 } _AccumuloProxy_createLocalUser_args__isset;
 
 class AccumuloProxy_createLocalUser_args {
  public:
 
+  AccumuloProxy_createLocalUser_args(const AccumuloProxy_createLocalUser_args&);
+  AccumuloProxy_createLocalUser_args& operator=(const AccumuloProxy_createLocalUser_args&);
   AccumuloProxy_createLocalUser_args() : login(), user(), password() {
   }
 
-  virtual ~AccumuloProxy_createLocalUser_args() throw() {}
-
+  virtual ~AccumuloProxy_createLocalUser_args() throw();
   std::string login;
   std::string user;
   std::string password;
 
   _AccumuloProxy_createLocalUser_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_password(const std::string& val) {
-    password = val;
-  }
+  void __set_password(const std::string& val);
 
   bool operator == (const AccumuloProxy_createLocalUser_args & rhs) const
   {
@@ -7726,8 +7225,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_createLocalUser_pargs() throw() {}
-
+  virtual ~AccumuloProxy_createLocalUser_pargs() throw();
   const std::string* login;
   const std::string* user;
   const std::string* password;
@@ -7738,30 +7236,27 @@
 
 typedef struct _AccumuloProxy_createLocalUser_result__isset {
   _AccumuloProxy_createLocalUser_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_createLocalUser_result__isset;
 
 class AccumuloProxy_createLocalUser_result {
  public:
 
+  AccumuloProxy_createLocalUser_result(const AccumuloProxy_createLocalUser_result&);
+  AccumuloProxy_createLocalUser_result& operator=(const AccumuloProxy_createLocalUser_result&);
   AccumuloProxy_createLocalUser_result() {
   }
 
-  virtual ~AccumuloProxy_createLocalUser_result() throw() {}
-
+  virtual ~AccumuloProxy_createLocalUser_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_createLocalUser_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_createLocalUser_result & rhs) const
   {
@@ -7784,16 +7279,15 @@
 
 typedef struct _AccumuloProxy_createLocalUser_presult__isset {
   _AccumuloProxy_createLocalUser_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_createLocalUser_presult__isset;
 
 class AccumuloProxy_createLocalUser_presult {
  public:
 
 
-  virtual ~AccumuloProxy_createLocalUser_presult() throw() {}
-
+  virtual ~AccumuloProxy_createLocalUser_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
@@ -7805,30 +7299,27 @@
 
 typedef struct _AccumuloProxy_dropLocalUser_args__isset {
   _AccumuloProxy_dropLocalUser_args__isset() : login(false), user(false) {}
-  bool login;
-  bool user;
+  bool login :1;
+  bool user :1;
 } _AccumuloProxy_dropLocalUser_args__isset;
 
 class AccumuloProxy_dropLocalUser_args {
  public:
 
+  AccumuloProxy_dropLocalUser_args(const AccumuloProxy_dropLocalUser_args&);
+  AccumuloProxy_dropLocalUser_args& operator=(const AccumuloProxy_dropLocalUser_args&);
   AccumuloProxy_dropLocalUser_args() : login(), user() {
   }
 
-  virtual ~AccumuloProxy_dropLocalUser_args() throw() {}
-
+  virtual ~AccumuloProxy_dropLocalUser_args() throw();
   std::string login;
   std::string user;
 
   _AccumuloProxy_dropLocalUser_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
   bool operator == (const AccumuloProxy_dropLocalUser_args & rhs) const
   {
@@ -7854,8 +7345,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_dropLocalUser_pargs() throw() {}
-
+  virtual ~AccumuloProxy_dropLocalUser_pargs() throw();
   const std::string* login;
   const std::string* user;
 
@@ -7865,30 +7355,27 @@
 
 typedef struct _AccumuloProxy_dropLocalUser_result__isset {
   _AccumuloProxy_dropLocalUser_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_dropLocalUser_result__isset;
 
 class AccumuloProxy_dropLocalUser_result {
  public:
 
+  AccumuloProxy_dropLocalUser_result(const AccumuloProxy_dropLocalUser_result&);
+  AccumuloProxy_dropLocalUser_result& operator=(const AccumuloProxy_dropLocalUser_result&);
   AccumuloProxy_dropLocalUser_result() {
   }
 
-  virtual ~AccumuloProxy_dropLocalUser_result() throw() {}
-
+  virtual ~AccumuloProxy_dropLocalUser_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_dropLocalUser_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_dropLocalUser_result & rhs) const
   {
@@ -7911,16 +7398,15 @@
 
 typedef struct _AccumuloProxy_dropLocalUser_presult__isset {
   _AccumuloProxy_dropLocalUser_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_dropLocalUser_presult__isset;
 
 class AccumuloProxy_dropLocalUser_presult {
  public:
 
 
-  virtual ~AccumuloProxy_dropLocalUser_presult() throw() {}
-
+  virtual ~AccumuloProxy_dropLocalUser_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
@@ -7932,30 +7418,27 @@
 
 typedef struct _AccumuloProxy_getUserAuthorizations_args__isset {
   _AccumuloProxy_getUserAuthorizations_args__isset() : login(false), user(false) {}
-  bool login;
-  bool user;
+  bool login :1;
+  bool user :1;
 } _AccumuloProxy_getUserAuthorizations_args__isset;
 
 class AccumuloProxy_getUserAuthorizations_args {
  public:
 
+  AccumuloProxy_getUserAuthorizations_args(const AccumuloProxy_getUserAuthorizations_args&);
+  AccumuloProxy_getUserAuthorizations_args& operator=(const AccumuloProxy_getUserAuthorizations_args&);
   AccumuloProxy_getUserAuthorizations_args() : login(), user() {
   }
 
-  virtual ~AccumuloProxy_getUserAuthorizations_args() throw() {}
-
+  virtual ~AccumuloProxy_getUserAuthorizations_args() throw();
   std::string login;
   std::string user;
 
   _AccumuloProxy_getUserAuthorizations_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
   bool operator == (const AccumuloProxy_getUserAuthorizations_args & rhs) const
   {
@@ -7981,8 +7464,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getUserAuthorizations_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getUserAuthorizations_pargs() throw();
   const std::string* login;
   const std::string* user;
 
@@ -7992,36 +7474,31 @@
 
 typedef struct _AccumuloProxy_getUserAuthorizations_result__isset {
   _AccumuloProxy_getUserAuthorizations_result__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_getUserAuthorizations_result__isset;
 
 class AccumuloProxy_getUserAuthorizations_result {
  public:
 
+  AccumuloProxy_getUserAuthorizations_result(const AccumuloProxy_getUserAuthorizations_result&);
+  AccumuloProxy_getUserAuthorizations_result& operator=(const AccumuloProxy_getUserAuthorizations_result&);
   AccumuloProxy_getUserAuthorizations_result() {
   }
 
-  virtual ~AccumuloProxy_getUserAuthorizations_result() throw() {}
-
+  virtual ~AccumuloProxy_getUserAuthorizations_result() throw();
   std::vector<std::string>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_getUserAuthorizations_result__isset __isset;
 
-  void __set_success(const std::vector<std::string> & val) {
-    success = val;
-  }
+  void __set_success(const std::vector<std::string> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_getUserAuthorizations_result & rhs) const
   {
@@ -8046,17 +7523,16 @@
 
 typedef struct _AccumuloProxy_getUserAuthorizations_presult__isset {
   _AccumuloProxy_getUserAuthorizations_presult__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_getUserAuthorizations_presult__isset;
 
 class AccumuloProxy_getUserAuthorizations_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getUserAuthorizations_presult() throw() {}
-
+  virtual ~AccumuloProxy_getUserAuthorizations_presult() throw();
   std::vector<std::string> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -8069,36 +7545,31 @@
 
 typedef struct _AccumuloProxy_grantSystemPermission_args__isset {
   _AccumuloProxy_grantSystemPermission_args__isset() : login(false), user(false), perm(false) {}
-  bool login;
-  bool user;
-  bool perm;
+  bool login :1;
+  bool user :1;
+  bool perm :1;
 } _AccumuloProxy_grantSystemPermission_args__isset;
 
 class AccumuloProxy_grantSystemPermission_args {
  public:
 
+  AccumuloProxy_grantSystemPermission_args(const AccumuloProxy_grantSystemPermission_args&);
+  AccumuloProxy_grantSystemPermission_args& operator=(const AccumuloProxy_grantSystemPermission_args&);
   AccumuloProxy_grantSystemPermission_args() : login(), user(), perm((SystemPermission::type)0) {
   }
 
-  virtual ~AccumuloProxy_grantSystemPermission_args() throw() {}
-
+  virtual ~AccumuloProxy_grantSystemPermission_args() throw();
   std::string login;
   std::string user;
   SystemPermission::type perm;
 
   _AccumuloProxy_grantSystemPermission_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_perm(const SystemPermission::type val) {
-    perm = val;
-  }
+  void __set_perm(const SystemPermission::type val);
 
   bool operator == (const AccumuloProxy_grantSystemPermission_args & rhs) const
   {
@@ -8126,8 +7597,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_grantSystemPermission_pargs() throw() {}
-
+  virtual ~AccumuloProxy_grantSystemPermission_pargs() throw();
   const std::string* login;
   const std::string* user;
   const SystemPermission::type* perm;
@@ -8138,30 +7608,27 @@
 
 typedef struct _AccumuloProxy_grantSystemPermission_result__isset {
   _AccumuloProxy_grantSystemPermission_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_grantSystemPermission_result__isset;
 
 class AccumuloProxy_grantSystemPermission_result {
  public:
 
+  AccumuloProxy_grantSystemPermission_result(const AccumuloProxy_grantSystemPermission_result&);
+  AccumuloProxy_grantSystemPermission_result& operator=(const AccumuloProxy_grantSystemPermission_result&);
   AccumuloProxy_grantSystemPermission_result() {
   }
 
-  virtual ~AccumuloProxy_grantSystemPermission_result() throw() {}
-
+  virtual ~AccumuloProxy_grantSystemPermission_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_grantSystemPermission_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_grantSystemPermission_result & rhs) const
   {
@@ -8184,16 +7651,15 @@
 
 typedef struct _AccumuloProxy_grantSystemPermission_presult__isset {
   _AccumuloProxy_grantSystemPermission_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_grantSystemPermission_presult__isset;
 
 class AccumuloProxy_grantSystemPermission_presult {
  public:
 
 
-  virtual ~AccumuloProxy_grantSystemPermission_presult() throw() {}
-
+  virtual ~AccumuloProxy_grantSystemPermission_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
@@ -8205,20 +7671,21 @@
 
 typedef struct _AccumuloProxy_grantTablePermission_args__isset {
   _AccumuloProxy_grantTablePermission_args__isset() : login(false), user(false), table(false), perm(false) {}
-  bool login;
-  bool user;
-  bool table;
-  bool perm;
+  bool login :1;
+  bool user :1;
+  bool table :1;
+  bool perm :1;
 } _AccumuloProxy_grantTablePermission_args__isset;
 
 class AccumuloProxy_grantTablePermission_args {
  public:
 
+  AccumuloProxy_grantTablePermission_args(const AccumuloProxy_grantTablePermission_args&);
+  AccumuloProxy_grantTablePermission_args& operator=(const AccumuloProxy_grantTablePermission_args&);
   AccumuloProxy_grantTablePermission_args() : login(), user(), table(), perm((TablePermission::type)0) {
   }
 
-  virtual ~AccumuloProxy_grantTablePermission_args() throw() {}
-
+  virtual ~AccumuloProxy_grantTablePermission_args() throw();
   std::string login;
   std::string user;
   std::string table;
@@ -8226,21 +7693,13 @@
 
   _AccumuloProxy_grantTablePermission_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_table(const std::string& val) {
-    table = val;
-  }
+  void __set_table(const std::string& val);
 
-  void __set_perm(const TablePermission::type val) {
-    perm = val;
-  }
+  void __set_perm(const TablePermission::type val);
 
   bool operator == (const AccumuloProxy_grantTablePermission_args & rhs) const
   {
@@ -8270,8 +7729,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_grantTablePermission_pargs() throw() {}
-
+  virtual ~AccumuloProxy_grantTablePermission_pargs() throw();
   const std::string* login;
   const std::string* user;
   const std::string* table;
@@ -8283,36 +7741,31 @@
 
 typedef struct _AccumuloProxy_grantTablePermission_result__isset {
   _AccumuloProxy_grantTablePermission_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_grantTablePermission_result__isset;
 
 class AccumuloProxy_grantTablePermission_result {
  public:
 
+  AccumuloProxy_grantTablePermission_result(const AccumuloProxy_grantTablePermission_result&);
+  AccumuloProxy_grantTablePermission_result& operator=(const AccumuloProxy_grantTablePermission_result&);
   AccumuloProxy_grantTablePermission_result() {
   }
 
-  virtual ~AccumuloProxy_grantTablePermission_result() throw() {}
-
+  virtual ~AccumuloProxy_grantTablePermission_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_grantTablePermission_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_grantTablePermission_result & rhs) const
   {
@@ -8337,17 +7790,16 @@
 
 typedef struct _AccumuloProxy_grantTablePermission_presult__isset {
   _AccumuloProxy_grantTablePermission_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_grantTablePermission_presult__isset;
 
 class AccumuloProxy_grantTablePermission_presult {
  public:
 
 
-  virtual ~AccumuloProxy_grantTablePermission_presult() throw() {}
-
+  virtual ~AccumuloProxy_grantTablePermission_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -8360,36 +7812,31 @@
 
 typedef struct _AccumuloProxy_hasSystemPermission_args__isset {
   _AccumuloProxy_hasSystemPermission_args__isset() : login(false), user(false), perm(false) {}
-  bool login;
-  bool user;
-  bool perm;
+  bool login :1;
+  bool user :1;
+  bool perm :1;
 } _AccumuloProxy_hasSystemPermission_args__isset;
 
 class AccumuloProxy_hasSystemPermission_args {
  public:
 
+  AccumuloProxy_hasSystemPermission_args(const AccumuloProxy_hasSystemPermission_args&);
+  AccumuloProxy_hasSystemPermission_args& operator=(const AccumuloProxy_hasSystemPermission_args&);
   AccumuloProxy_hasSystemPermission_args() : login(), user(), perm((SystemPermission::type)0) {
   }
 
-  virtual ~AccumuloProxy_hasSystemPermission_args() throw() {}
-
+  virtual ~AccumuloProxy_hasSystemPermission_args() throw();
   std::string login;
   std::string user;
   SystemPermission::type perm;
 
   _AccumuloProxy_hasSystemPermission_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_perm(const SystemPermission::type val) {
-    perm = val;
-  }
+  void __set_perm(const SystemPermission::type val);
 
   bool operator == (const AccumuloProxy_hasSystemPermission_args & rhs) const
   {
@@ -8417,8 +7864,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_hasSystemPermission_pargs() throw() {}
-
+  virtual ~AccumuloProxy_hasSystemPermission_pargs() throw();
   const std::string* login;
   const std::string* user;
   const SystemPermission::type* perm;
@@ -8429,36 +7875,31 @@
 
 typedef struct _AccumuloProxy_hasSystemPermission_result__isset {
   _AccumuloProxy_hasSystemPermission_result__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_hasSystemPermission_result__isset;
 
 class AccumuloProxy_hasSystemPermission_result {
  public:
 
+  AccumuloProxy_hasSystemPermission_result(const AccumuloProxy_hasSystemPermission_result&);
+  AccumuloProxy_hasSystemPermission_result& operator=(const AccumuloProxy_hasSystemPermission_result&);
   AccumuloProxy_hasSystemPermission_result() : success(0) {
   }
 
-  virtual ~AccumuloProxy_hasSystemPermission_result() throw() {}
-
+  virtual ~AccumuloProxy_hasSystemPermission_result() throw();
   bool success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_hasSystemPermission_result__isset __isset;
 
-  void __set_success(const bool val) {
-    success = val;
-  }
+  void __set_success(const bool val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_hasSystemPermission_result & rhs) const
   {
@@ -8483,17 +7924,16 @@
 
 typedef struct _AccumuloProxy_hasSystemPermission_presult__isset {
   _AccumuloProxy_hasSystemPermission_presult__isset() : success(false), ouch1(false), ouch2(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_hasSystemPermission_presult__isset;
 
 class AccumuloProxy_hasSystemPermission_presult {
  public:
 
 
-  virtual ~AccumuloProxy_hasSystemPermission_presult() throw() {}
-
+  virtual ~AccumuloProxy_hasSystemPermission_presult() throw();
   bool* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -8506,20 +7946,21 @@
 
 typedef struct _AccumuloProxy_hasTablePermission_args__isset {
   _AccumuloProxy_hasTablePermission_args__isset() : login(false), user(false), table(false), perm(false) {}
-  bool login;
-  bool user;
-  bool table;
-  bool perm;
+  bool login :1;
+  bool user :1;
+  bool table :1;
+  bool perm :1;
 } _AccumuloProxy_hasTablePermission_args__isset;
 
 class AccumuloProxy_hasTablePermission_args {
  public:
 
+  AccumuloProxy_hasTablePermission_args(const AccumuloProxy_hasTablePermission_args&);
+  AccumuloProxy_hasTablePermission_args& operator=(const AccumuloProxy_hasTablePermission_args&);
   AccumuloProxy_hasTablePermission_args() : login(), user(), table(), perm((TablePermission::type)0) {
   }
 
-  virtual ~AccumuloProxy_hasTablePermission_args() throw() {}
-
+  virtual ~AccumuloProxy_hasTablePermission_args() throw();
   std::string login;
   std::string user;
   std::string table;
@@ -8527,21 +7968,13 @@
 
   _AccumuloProxy_hasTablePermission_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_table(const std::string& val) {
-    table = val;
-  }
+  void __set_table(const std::string& val);
 
-  void __set_perm(const TablePermission::type val) {
-    perm = val;
-  }
+  void __set_perm(const TablePermission::type val);
 
   bool operator == (const AccumuloProxy_hasTablePermission_args & rhs) const
   {
@@ -8571,8 +8004,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_hasTablePermission_pargs() throw() {}
-
+  virtual ~AccumuloProxy_hasTablePermission_pargs() throw();
   const std::string* login;
   const std::string* user;
   const std::string* table;
@@ -8584,20 +8016,21 @@
 
 typedef struct _AccumuloProxy_hasTablePermission_result__isset {
   _AccumuloProxy_hasTablePermission_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_hasTablePermission_result__isset;
 
 class AccumuloProxy_hasTablePermission_result {
  public:
 
+  AccumuloProxy_hasTablePermission_result(const AccumuloProxy_hasTablePermission_result&);
+  AccumuloProxy_hasTablePermission_result& operator=(const AccumuloProxy_hasTablePermission_result&);
   AccumuloProxy_hasTablePermission_result() : success(0) {
   }
 
-  virtual ~AccumuloProxy_hasTablePermission_result() throw() {}
-
+  virtual ~AccumuloProxy_hasTablePermission_result() throw();
   bool success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -8605,21 +8038,13 @@
 
   _AccumuloProxy_hasTablePermission_result__isset __isset;
 
-  void __set_success(const bool val) {
-    success = val;
-  }
+  void __set_success(const bool val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_hasTablePermission_result & rhs) const
   {
@@ -8646,18 +8071,17 @@
 
 typedef struct _AccumuloProxy_hasTablePermission_presult__isset {
   _AccumuloProxy_hasTablePermission_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_hasTablePermission_presult__isset;
 
 class AccumuloProxy_hasTablePermission_presult {
  public:
 
 
-  virtual ~AccumuloProxy_hasTablePermission_presult() throw() {}
-
+  virtual ~AccumuloProxy_hasTablePermission_presult() throw();
   bool* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -8671,24 +8095,23 @@
 
 typedef struct _AccumuloProxy_listLocalUsers_args__isset {
   _AccumuloProxy_listLocalUsers_args__isset() : login(false) {}
-  bool login;
+  bool login :1;
 } _AccumuloProxy_listLocalUsers_args__isset;
 
 class AccumuloProxy_listLocalUsers_args {
  public:
 
+  AccumuloProxy_listLocalUsers_args(const AccumuloProxy_listLocalUsers_args&);
+  AccumuloProxy_listLocalUsers_args& operator=(const AccumuloProxy_listLocalUsers_args&);
   AccumuloProxy_listLocalUsers_args() : login() {
   }
 
-  virtual ~AccumuloProxy_listLocalUsers_args() throw() {}
-
+  virtual ~AccumuloProxy_listLocalUsers_args() throw();
   std::string login;
 
   _AccumuloProxy_listLocalUsers_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
   bool operator == (const AccumuloProxy_listLocalUsers_args & rhs) const
   {
@@ -8712,8 +8135,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_listLocalUsers_pargs() throw() {}
-
+  virtual ~AccumuloProxy_listLocalUsers_pargs() throw();
   const std::string* login;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -8722,20 +8144,21 @@
 
 typedef struct _AccumuloProxy_listLocalUsers_result__isset {
   _AccumuloProxy_listLocalUsers_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_listLocalUsers_result__isset;
 
 class AccumuloProxy_listLocalUsers_result {
  public:
 
+  AccumuloProxy_listLocalUsers_result(const AccumuloProxy_listLocalUsers_result&);
+  AccumuloProxy_listLocalUsers_result& operator=(const AccumuloProxy_listLocalUsers_result&);
   AccumuloProxy_listLocalUsers_result() {
   }
 
-  virtual ~AccumuloProxy_listLocalUsers_result() throw() {}
-
+  virtual ~AccumuloProxy_listLocalUsers_result() throw();
   std::set<std::string>  success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -8743,21 +8166,13 @@
 
   _AccumuloProxy_listLocalUsers_result__isset __isset;
 
-  void __set_success(const std::set<std::string> & val) {
-    success = val;
-  }
+  void __set_success(const std::set<std::string> & val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_listLocalUsers_result & rhs) const
   {
@@ -8784,18 +8199,17 @@
 
 typedef struct _AccumuloProxy_listLocalUsers_presult__isset {
   _AccumuloProxy_listLocalUsers_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_listLocalUsers_presult__isset;
 
 class AccumuloProxy_listLocalUsers_presult {
  public:
 
 
-  virtual ~AccumuloProxy_listLocalUsers_presult() throw() {}
-
+  virtual ~AccumuloProxy_listLocalUsers_presult() throw();
   std::set<std::string> * success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -8809,36 +8223,31 @@
 
 typedef struct _AccumuloProxy_revokeSystemPermission_args__isset {
   _AccumuloProxy_revokeSystemPermission_args__isset() : login(false), user(false), perm(false) {}
-  bool login;
-  bool user;
-  bool perm;
+  bool login :1;
+  bool user :1;
+  bool perm :1;
 } _AccumuloProxy_revokeSystemPermission_args__isset;
 
 class AccumuloProxy_revokeSystemPermission_args {
  public:
 
+  AccumuloProxy_revokeSystemPermission_args(const AccumuloProxy_revokeSystemPermission_args&);
+  AccumuloProxy_revokeSystemPermission_args& operator=(const AccumuloProxy_revokeSystemPermission_args&);
   AccumuloProxy_revokeSystemPermission_args() : login(), user(), perm((SystemPermission::type)0) {
   }
 
-  virtual ~AccumuloProxy_revokeSystemPermission_args() throw() {}
-
+  virtual ~AccumuloProxy_revokeSystemPermission_args() throw();
   std::string login;
   std::string user;
   SystemPermission::type perm;
 
   _AccumuloProxy_revokeSystemPermission_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_perm(const SystemPermission::type val) {
-    perm = val;
-  }
+  void __set_perm(const SystemPermission::type val);
 
   bool operator == (const AccumuloProxy_revokeSystemPermission_args & rhs) const
   {
@@ -8866,8 +8275,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_revokeSystemPermission_pargs() throw() {}
-
+  virtual ~AccumuloProxy_revokeSystemPermission_pargs() throw();
   const std::string* login;
   const std::string* user;
   const SystemPermission::type* perm;
@@ -8878,30 +8286,27 @@
 
 typedef struct _AccumuloProxy_revokeSystemPermission_result__isset {
   _AccumuloProxy_revokeSystemPermission_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_revokeSystemPermission_result__isset;
 
 class AccumuloProxy_revokeSystemPermission_result {
  public:
 
+  AccumuloProxy_revokeSystemPermission_result(const AccumuloProxy_revokeSystemPermission_result&);
+  AccumuloProxy_revokeSystemPermission_result& operator=(const AccumuloProxy_revokeSystemPermission_result&);
   AccumuloProxy_revokeSystemPermission_result() {
   }
 
-  virtual ~AccumuloProxy_revokeSystemPermission_result() throw() {}
-
+  virtual ~AccumuloProxy_revokeSystemPermission_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
   _AccumuloProxy_revokeSystemPermission_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_revokeSystemPermission_result & rhs) const
   {
@@ -8924,16 +8329,15 @@
 
 typedef struct _AccumuloProxy_revokeSystemPermission_presult__isset {
   _AccumuloProxy_revokeSystemPermission_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_revokeSystemPermission_presult__isset;
 
 class AccumuloProxy_revokeSystemPermission_presult {
  public:
 
 
-  virtual ~AccumuloProxy_revokeSystemPermission_presult() throw() {}
-
+  virtual ~AccumuloProxy_revokeSystemPermission_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
 
@@ -8945,20 +8349,21 @@
 
 typedef struct _AccumuloProxy_revokeTablePermission_args__isset {
   _AccumuloProxy_revokeTablePermission_args__isset() : login(false), user(false), table(false), perm(false) {}
-  bool login;
-  bool user;
-  bool table;
-  bool perm;
+  bool login :1;
+  bool user :1;
+  bool table :1;
+  bool perm :1;
 } _AccumuloProxy_revokeTablePermission_args__isset;
 
 class AccumuloProxy_revokeTablePermission_args {
  public:
 
+  AccumuloProxy_revokeTablePermission_args(const AccumuloProxy_revokeTablePermission_args&);
+  AccumuloProxy_revokeTablePermission_args& operator=(const AccumuloProxy_revokeTablePermission_args&);
   AccumuloProxy_revokeTablePermission_args() : login(), user(), table(), perm((TablePermission::type)0) {
   }
 
-  virtual ~AccumuloProxy_revokeTablePermission_args() throw() {}
-
+  virtual ~AccumuloProxy_revokeTablePermission_args() throw();
   std::string login;
   std::string user;
   std::string table;
@@ -8966,21 +8371,13 @@
 
   _AccumuloProxy_revokeTablePermission_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_table(const std::string& val) {
-    table = val;
-  }
+  void __set_table(const std::string& val);
 
-  void __set_perm(const TablePermission::type val) {
-    perm = val;
-  }
+  void __set_perm(const TablePermission::type val);
 
   bool operator == (const AccumuloProxy_revokeTablePermission_args & rhs) const
   {
@@ -9010,8 +8407,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_revokeTablePermission_pargs() throw() {}
-
+  virtual ~AccumuloProxy_revokeTablePermission_pargs() throw();
   const std::string* login;
   const std::string* user;
   const std::string* table;
@@ -9023,36 +8419,31 @@
 
 typedef struct _AccumuloProxy_revokeTablePermission_result__isset {
   _AccumuloProxy_revokeTablePermission_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_revokeTablePermission_result__isset;
 
 class AccumuloProxy_revokeTablePermission_result {
  public:
 
+  AccumuloProxy_revokeTablePermission_result(const AccumuloProxy_revokeTablePermission_result&);
+  AccumuloProxy_revokeTablePermission_result& operator=(const AccumuloProxy_revokeTablePermission_result&);
   AccumuloProxy_revokeTablePermission_result() {
   }
 
-  virtual ~AccumuloProxy_revokeTablePermission_result() throw() {}
-
+  virtual ~AccumuloProxy_revokeTablePermission_result() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
 
   _AccumuloProxy_revokeTablePermission_result__isset __isset;
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_revokeTablePermission_result & rhs) const
   {
@@ -9077,17 +8468,16 @@
 
 typedef struct _AccumuloProxy_revokeTablePermission_presult__isset {
   _AccumuloProxy_revokeTablePermission_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_revokeTablePermission_presult__isset;
 
 class AccumuloProxy_revokeTablePermission_presult {
  public:
 
 
-  virtual ~AccumuloProxy_revokeTablePermission_presult() throw() {}
-
+  virtual ~AccumuloProxy_revokeTablePermission_presult() throw();
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -9098,38 +8488,440 @@
 
 };
 
+typedef struct _AccumuloProxy_grantNamespacePermission_args__isset {
+  _AccumuloProxy_grantNamespacePermission_args__isset() : login(false), user(false), namespaceName(false), perm(false) {}
+  bool login :1;
+  bool user :1;
+  bool namespaceName :1;
+  bool perm :1;
+} _AccumuloProxy_grantNamespacePermission_args__isset;
+
+class AccumuloProxy_grantNamespacePermission_args {
+ public:
+
+  AccumuloProxy_grantNamespacePermission_args(const AccumuloProxy_grantNamespacePermission_args&);
+  AccumuloProxy_grantNamespacePermission_args& operator=(const AccumuloProxy_grantNamespacePermission_args&);
+  AccumuloProxy_grantNamespacePermission_args() : login(), user(), namespaceName(), perm((NamespacePermission::type)0) {
+  }
+
+  virtual ~AccumuloProxy_grantNamespacePermission_args() throw();
+  std::string login;
+  std::string user;
+  std::string namespaceName;
+  NamespacePermission::type perm;
+
+  _AccumuloProxy_grantNamespacePermission_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_user(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_perm(const NamespacePermission::type val);
+
+  bool operator == (const AccumuloProxy_grantNamespacePermission_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(user == rhs.user))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(perm == rhs.perm))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_grantNamespacePermission_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_grantNamespacePermission_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_grantNamespacePermission_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_grantNamespacePermission_pargs() throw();
+  const std::string* login;
+  const std::string* user;
+  const std::string* namespaceName;
+  const NamespacePermission::type* perm;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_grantNamespacePermission_result__isset {
+  _AccumuloProxy_grantNamespacePermission_result__isset() : ouch1(false), ouch2(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_grantNamespacePermission_result__isset;
+
+class AccumuloProxy_grantNamespacePermission_result {
+ public:
+
+  AccumuloProxy_grantNamespacePermission_result(const AccumuloProxy_grantNamespacePermission_result&);
+  AccumuloProxy_grantNamespacePermission_result& operator=(const AccumuloProxy_grantNamespacePermission_result&);
+  AccumuloProxy_grantNamespacePermission_result() {
+  }
+
+  virtual ~AccumuloProxy_grantNamespacePermission_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_grantNamespacePermission_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  bool operator == (const AccumuloProxy_grantNamespacePermission_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_grantNamespacePermission_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_grantNamespacePermission_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_grantNamespacePermission_presult__isset {
+  _AccumuloProxy_grantNamespacePermission_presult__isset() : ouch1(false), ouch2(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_grantNamespacePermission_presult__isset;
+
+class AccumuloProxy_grantNamespacePermission_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_grantNamespacePermission_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_grantNamespacePermission_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_hasNamespacePermission_args__isset {
+  _AccumuloProxy_hasNamespacePermission_args__isset() : login(false), user(false), namespaceName(false), perm(false) {}
+  bool login :1;
+  bool user :1;
+  bool namespaceName :1;
+  bool perm :1;
+} _AccumuloProxy_hasNamespacePermission_args__isset;
+
+class AccumuloProxy_hasNamespacePermission_args {
+ public:
+
+  AccumuloProxy_hasNamespacePermission_args(const AccumuloProxy_hasNamespacePermission_args&);
+  AccumuloProxy_hasNamespacePermission_args& operator=(const AccumuloProxy_hasNamespacePermission_args&);
+  AccumuloProxy_hasNamespacePermission_args() : login(), user(), namespaceName(), perm((NamespacePermission::type)0) {
+  }
+
+  virtual ~AccumuloProxy_hasNamespacePermission_args() throw();
+  std::string login;
+  std::string user;
+  std::string namespaceName;
+  NamespacePermission::type perm;
+
+  _AccumuloProxy_hasNamespacePermission_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_user(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_perm(const NamespacePermission::type val);
+
+  bool operator == (const AccumuloProxy_hasNamespacePermission_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(user == rhs.user))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(perm == rhs.perm))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_hasNamespacePermission_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_hasNamespacePermission_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_hasNamespacePermission_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_hasNamespacePermission_pargs() throw();
+  const std::string* login;
+  const std::string* user;
+  const std::string* namespaceName;
+  const NamespacePermission::type* perm;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_hasNamespacePermission_result__isset {
+  _AccumuloProxy_hasNamespacePermission_result__isset() : success(false), ouch1(false), ouch2(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_hasNamespacePermission_result__isset;
+
+class AccumuloProxy_hasNamespacePermission_result {
+ public:
+
+  AccumuloProxy_hasNamespacePermission_result(const AccumuloProxy_hasNamespacePermission_result&);
+  AccumuloProxy_hasNamespacePermission_result& operator=(const AccumuloProxy_hasNamespacePermission_result&);
+  AccumuloProxy_hasNamespacePermission_result() : success(0) {
+  }
+
+  virtual ~AccumuloProxy_hasNamespacePermission_result() throw();
+  bool success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_hasNamespacePermission_result__isset __isset;
+
+  void __set_success(const bool val);
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  bool operator == (const AccumuloProxy_hasNamespacePermission_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_hasNamespacePermission_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_hasNamespacePermission_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_hasNamespacePermission_presult__isset {
+  _AccumuloProxy_hasNamespacePermission_presult__isset() : success(false), ouch1(false), ouch2(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_hasNamespacePermission_presult__isset;
+
+class AccumuloProxy_hasNamespacePermission_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_hasNamespacePermission_presult() throw();
+  bool* success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_hasNamespacePermission_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_revokeNamespacePermission_args__isset {
+  _AccumuloProxy_revokeNamespacePermission_args__isset() : login(false), user(false), namespaceName(false), perm(false) {}
+  bool login :1;
+  bool user :1;
+  bool namespaceName :1;
+  bool perm :1;
+} _AccumuloProxy_revokeNamespacePermission_args__isset;
+
+class AccumuloProxy_revokeNamespacePermission_args {
+ public:
+
+  AccumuloProxy_revokeNamespacePermission_args(const AccumuloProxy_revokeNamespacePermission_args&);
+  AccumuloProxy_revokeNamespacePermission_args& operator=(const AccumuloProxy_revokeNamespacePermission_args&);
+  AccumuloProxy_revokeNamespacePermission_args() : login(), user(), namespaceName(), perm((NamespacePermission::type)0) {
+  }
+
+  virtual ~AccumuloProxy_revokeNamespacePermission_args() throw();
+  std::string login;
+  std::string user;
+  std::string namespaceName;
+  NamespacePermission::type perm;
+
+  _AccumuloProxy_revokeNamespacePermission_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_user(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_perm(const NamespacePermission::type val);
+
+  bool operator == (const AccumuloProxy_revokeNamespacePermission_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(user == rhs.user))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(perm == rhs.perm))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_revokeNamespacePermission_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_revokeNamespacePermission_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_revokeNamespacePermission_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_revokeNamespacePermission_pargs() throw();
+  const std::string* login;
+  const std::string* user;
+  const std::string* namespaceName;
+  const NamespacePermission::type* perm;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_revokeNamespacePermission_result__isset {
+  _AccumuloProxy_revokeNamespacePermission_result__isset() : ouch1(false), ouch2(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_revokeNamespacePermission_result__isset;
+
+class AccumuloProxy_revokeNamespacePermission_result {
+ public:
+
+  AccumuloProxy_revokeNamespacePermission_result(const AccumuloProxy_revokeNamespacePermission_result&);
+  AccumuloProxy_revokeNamespacePermission_result& operator=(const AccumuloProxy_revokeNamespacePermission_result&);
+  AccumuloProxy_revokeNamespacePermission_result() {
+  }
+
+  virtual ~AccumuloProxy_revokeNamespacePermission_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_revokeNamespacePermission_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  bool operator == (const AccumuloProxy_revokeNamespacePermission_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_revokeNamespacePermission_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_revokeNamespacePermission_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_revokeNamespacePermission_presult__isset {
+  _AccumuloProxy_revokeNamespacePermission_presult__isset() : ouch1(false), ouch2(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_revokeNamespacePermission_presult__isset;
+
+class AccumuloProxy_revokeNamespacePermission_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_revokeNamespacePermission_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_revokeNamespacePermission_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
 typedef struct _AccumuloProxy_createBatchScanner_args__isset {
   _AccumuloProxy_createBatchScanner_args__isset() : login(false), tableName(false), options(false) {}
-  bool login;
-  bool tableName;
-  bool options;
+  bool login :1;
+  bool tableName :1;
+  bool options :1;
 } _AccumuloProxy_createBatchScanner_args__isset;
 
 class AccumuloProxy_createBatchScanner_args {
  public:
 
+  AccumuloProxy_createBatchScanner_args(const AccumuloProxy_createBatchScanner_args&);
+  AccumuloProxy_createBatchScanner_args& operator=(const AccumuloProxy_createBatchScanner_args&);
   AccumuloProxy_createBatchScanner_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_createBatchScanner_args() throw() {}
-
+  virtual ~AccumuloProxy_createBatchScanner_args() throw();
   std::string login;
   std::string tableName;
   BatchScanOptions options;
 
   _AccumuloProxy_createBatchScanner_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_options(const BatchScanOptions& val) {
-    options = val;
-  }
+  void __set_options(const BatchScanOptions& val);
 
   bool operator == (const AccumuloProxy_createBatchScanner_args & rhs) const
   {
@@ -9157,8 +8949,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_createBatchScanner_pargs() throw() {}
-
+  virtual ~AccumuloProxy_createBatchScanner_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const BatchScanOptions* options;
@@ -9169,20 +8960,21 @@
 
 typedef struct _AccumuloProxy_createBatchScanner_result__isset {
   _AccumuloProxy_createBatchScanner_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_createBatchScanner_result__isset;
 
 class AccumuloProxy_createBatchScanner_result {
  public:
 
+  AccumuloProxy_createBatchScanner_result(const AccumuloProxy_createBatchScanner_result&);
+  AccumuloProxy_createBatchScanner_result& operator=(const AccumuloProxy_createBatchScanner_result&);
   AccumuloProxy_createBatchScanner_result() : success() {
   }
 
-  virtual ~AccumuloProxy_createBatchScanner_result() throw() {}
-
+  virtual ~AccumuloProxy_createBatchScanner_result() throw();
   std::string success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -9190,21 +8982,13 @@
 
   _AccumuloProxy_createBatchScanner_result__isset __isset;
 
-  void __set_success(const std::string& val) {
-    success = val;
-  }
+  void __set_success(const std::string& val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_createBatchScanner_result & rhs) const
   {
@@ -9231,18 +9015,17 @@
 
 typedef struct _AccumuloProxy_createBatchScanner_presult__isset {
   _AccumuloProxy_createBatchScanner_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_createBatchScanner_presult__isset;
 
 class AccumuloProxy_createBatchScanner_presult {
  public:
 
 
-  virtual ~AccumuloProxy_createBatchScanner_presult() throw() {}
-
+  virtual ~AccumuloProxy_createBatchScanner_presult() throw();
   std::string* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -9256,36 +9039,31 @@
 
 typedef struct _AccumuloProxy_createScanner_args__isset {
   _AccumuloProxy_createScanner_args__isset() : login(false), tableName(false), options(false) {}
-  bool login;
-  bool tableName;
-  bool options;
+  bool login :1;
+  bool tableName :1;
+  bool options :1;
 } _AccumuloProxy_createScanner_args__isset;
 
 class AccumuloProxy_createScanner_args {
  public:
 
+  AccumuloProxy_createScanner_args(const AccumuloProxy_createScanner_args&);
+  AccumuloProxy_createScanner_args& operator=(const AccumuloProxy_createScanner_args&);
   AccumuloProxy_createScanner_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_createScanner_args() throw() {}
-
+  virtual ~AccumuloProxy_createScanner_args() throw();
   std::string login;
   std::string tableName;
   ScanOptions options;
 
   _AccumuloProxy_createScanner_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_options(const ScanOptions& val) {
-    options = val;
-  }
+  void __set_options(const ScanOptions& val);
 
   bool operator == (const AccumuloProxy_createScanner_args & rhs) const
   {
@@ -9313,8 +9091,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_createScanner_pargs() throw() {}
-
+  virtual ~AccumuloProxy_createScanner_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const ScanOptions* options;
@@ -9325,20 +9102,21 @@
 
 typedef struct _AccumuloProxy_createScanner_result__isset {
   _AccumuloProxy_createScanner_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_createScanner_result__isset;
 
 class AccumuloProxy_createScanner_result {
  public:
 
+  AccumuloProxy_createScanner_result(const AccumuloProxy_createScanner_result&);
+  AccumuloProxy_createScanner_result& operator=(const AccumuloProxy_createScanner_result&);
   AccumuloProxy_createScanner_result() : success() {
   }
 
-  virtual ~AccumuloProxy_createScanner_result() throw() {}
-
+  virtual ~AccumuloProxy_createScanner_result() throw();
   std::string success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -9346,21 +9124,13 @@
 
   _AccumuloProxy_createScanner_result__isset __isset;
 
-  void __set_success(const std::string& val) {
-    success = val;
-  }
+  void __set_success(const std::string& val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_createScanner_result & rhs) const
   {
@@ -9387,18 +9157,17 @@
 
 typedef struct _AccumuloProxy_createScanner_presult__isset {
   _AccumuloProxy_createScanner_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_createScanner_presult__isset;
 
 class AccumuloProxy_createScanner_presult {
  public:
 
 
-  virtual ~AccumuloProxy_createScanner_presult() throw() {}
-
+  virtual ~AccumuloProxy_createScanner_presult() throw();
   std::string* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -9412,24 +9181,23 @@
 
 typedef struct _AccumuloProxy_hasNext_args__isset {
   _AccumuloProxy_hasNext_args__isset() : scanner(false) {}
-  bool scanner;
+  bool scanner :1;
 } _AccumuloProxy_hasNext_args__isset;
 
 class AccumuloProxy_hasNext_args {
  public:
 
+  AccumuloProxy_hasNext_args(const AccumuloProxy_hasNext_args&);
+  AccumuloProxy_hasNext_args& operator=(const AccumuloProxy_hasNext_args&);
   AccumuloProxy_hasNext_args() : scanner() {
   }
 
-  virtual ~AccumuloProxy_hasNext_args() throw() {}
-
+  virtual ~AccumuloProxy_hasNext_args() throw();
   std::string scanner;
 
   _AccumuloProxy_hasNext_args__isset __isset;
 
-  void __set_scanner(const std::string& val) {
-    scanner = val;
-  }
+  void __set_scanner(const std::string& val);
 
   bool operator == (const AccumuloProxy_hasNext_args & rhs) const
   {
@@ -9453,8 +9221,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_hasNext_pargs() throw() {}
-
+  virtual ~AccumuloProxy_hasNext_pargs() throw();
   const std::string* scanner;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -9463,30 +9230,27 @@
 
 typedef struct _AccumuloProxy_hasNext_result__isset {
   _AccumuloProxy_hasNext_result__isset() : success(false), ouch1(false) {}
-  bool success;
-  bool ouch1;
+  bool success :1;
+  bool ouch1 :1;
 } _AccumuloProxy_hasNext_result__isset;
 
 class AccumuloProxy_hasNext_result {
  public:
 
+  AccumuloProxy_hasNext_result(const AccumuloProxy_hasNext_result&);
+  AccumuloProxy_hasNext_result& operator=(const AccumuloProxy_hasNext_result&);
   AccumuloProxy_hasNext_result() : success(0) {
   }
 
-  virtual ~AccumuloProxy_hasNext_result() throw() {}
-
+  virtual ~AccumuloProxy_hasNext_result() throw();
   bool success;
   UnknownScanner ouch1;
 
   _AccumuloProxy_hasNext_result__isset __isset;
 
-  void __set_success(const bool val) {
-    success = val;
-  }
+  void __set_success(const bool val);
 
-  void __set_ouch1(const UnknownScanner& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const UnknownScanner& val);
 
   bool operator == (const AccumuloProxy_hasNext_result & rhs) const
   {
@@ -9509,16 +9273,15 @@
 
 typedef struct _AccumuloProxy_hasNext_presult__isset {
   _AccumuloProxy_hasNext_presult__isset() : success(false), ouch1(false) {}
-  bool success;
-  bool ouch1;
+  bool success :1;
+  bool ouch1 :1;
 } _AccumuloProxy_hasNext_presult__isset;
 
 class AccumuloProxy_hasNext_presult {
  public:
 
 
-  virtual ~AccumuloProxy_hasNext_presult() throw() {}
-
+  virtual ~AccumuloProxy_hasNext_presult() throw();
   bool* success;
   UnknownScanner ouch1;
 
@@ -9530,24 +9293,23 @@
 
 typedef struct _AccumuloProxy_nextEntry_args__isset {
   _AccumuloProxy_nextEntry_args__isset() : scanner(false) {}
-  bool scanner;
+  bool scanner :1;
 } _AccumuloProxy_nextEntry_args__isset;
 
 class AccumuloProxy_nextEntry_args {
  public:
 
+  AccumuloProxy_nextEntry_args(const AccumuloProxy_nextEntry_args&);
+  AccumuloProxy_nextEntry_args& operator=(const AccumuloProxy_nextEntry_args&);
   AccumuloProxy_nextEntry_args() : scanner() {
   }
 
-  virtual ~AccumuloProxy_nextEntry_args() throw() {}
-
+  virtual ~AccumuloProxy_nextEntry_args() throw();
   std::string scanner;
 
   _AccumuloProxy_nextEntry_args__isset __isset;
 
-  void __set_scanner(const std::string& val) {
-    scanner = val;
-  }
+  void __set_scanner(const std::string& val);
 
   bool operator == (const AccumuloProxy_nextEntry_args & rhs) const
   {
@@ -9571,8 +9333,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_nextEntry_pargs() throw() {}
-
+  virtual ~AccumuloProxy_nextEntry_pargs() throw();
   const std::string* scanner;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -9581,20 +9342,21 @@
 
 typedef struct _AccumuloProxy_nextEntry_result__isset {
   _AccumuloProxy_nextEntry_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_nextEntry_result__isset;
 
 class AccumuloProxy_nextEntry_result {
  public:
 
+  AccumuloProxy_nextEntry_result(const AccumuloProxy_nextEntry_result&);
+  AccumuloProxy_nextEntry_result& operator=(const AccumuloProxy_nextEntry_result&);
   AccumuloProxy_nextEntry_result() {
   }
 
-  virtual ~AccumuloProxy_nextEntry_result() throw() {}
-
+  virtual ~AccumuloProxy_nextEntry_result() throw();
   KeyValueAndPeek success;
   NoMoreEntriesException ouch1;
   UnknownScanner ouch2;
@@ -9602,21 +9364,13 @@
 
   _AccumuloProxy_nextEntry_result__isset __isset;
 
-  void __set_success(const KeyValueAndPeek& val) {
-    success = val;
-  }
+  void __set_success(const KeyValueAndPeek& val);
 
-  void __set_ouch1(const NoMoreEntriesException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const NoMoreEntriesException& val);
 
-  void __set_ouch2(const UnknownScanner& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const UnknownScanner& val);
 
-  void __set_ouch3(const AccumuloSecurityException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_nextEntry_result & rhs) const
   {
@@ -9643,18 +9397,17 @@
 
 typedef struct _AccumuloProxy_nextEntry_presult__isset {
   _AccumuloProxy_nextEntry_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_nextEntry_presult__isset;
 
 class AccumuloProxy_nextEntry_presult {
  public:
 
 
-  virtual ~AccumuloProxy_nextEntry_presult() throw() {}
-
+  virtual ~AccumuloProxy_nextEntry_presult() throw();
   KeyValueAndPeek* success;
   NoMoreEntriesException ouch1;
   UnknownScanner ouch2;
@@ -9668,30 +9421,27 @@
 
 typedef struct _AccumuloProxy_nextK_args__isset {
   _AccumuloProxy_nextK_args__isset() : scanner(false), k(false) {}
-  bool scanner;
-  bool k;
+  bool scanner :1;
+  bool k :1;
 } _AccumuloProxy_nextK_args__isset;
 
 class AccumuloProxy_nextK_args {
  public:
 
+  AccumuloProxy_nextK_args(const AccumuloProxy_nextK_args&);
+  AccumuloProxy_nextK_args& operator=(const AccumuloProxy_nextK_args&);
   AccumuloProxy_nextK_args() : scanner(), k(0) {
   }
 
-  virtual ~AccumuloProxy_nextK_args() throw() {}
-
+  virtual ~AccumuloProxy_nextK_args() throw();
   std::string scanner;
   int32_t k;
 
   _AccumuloProxy_nextK_args__isset __isset;
 
-  void __set_scanner(const std::string& val) {
-    scanner = val;
-  }
+  void __set_scanner(const std::string& val);
 
-  void __set_k(const int32_t val) {
-    k = val;
-  }
+  void __set_k(const int32_t val);
 
   bool operator == (const AccumuloProxy_nextK_args & rhs) const
   {
@@ -9717,8 +9467,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_nextK_pargs() throw() {}
-
+  virtual ~AccumuloProxy_nextK_pargs() throw();
   const std::string* scanner;
   const int32_t* k;
 
@@ -9728,20 +9477,21 @@
 
 typedef struct _AccumuloProxy_nextK_result__isset {
   _AccumuloProxy_nextK_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_nextK_result__isset;
 
 class AccumuloProxy_nextK_result {
  public:
 
+  AccumuloProxy_nextK_result(const AccumuloProxy_nextK_result&);
+  AccumuloProxy_nextK_result& operator=(const AccumuloProxy_nextK_result&);
   AccumuloProxy_nextK_result() {
   }
 
-  virtual ~AccumuloProxy_nextK_result() throw() {}
-
+  virtual ~AccumuloProxy_nextK_result() throw();
   ScanResult success;
   NoMoreEntriesException ouch1;
   UnknownScanner ouch2;
@@ -9749,21 +9499,13 @@
 
   _AccumuloProxy_nextK_result__isset __isset;
 
-  void __set_success(const ScanResult& val) {
-    success = val;
-  }
+  void __set_success(const ScanResult& val);
 
-  void __set_ouch1(const NoMoreEntriesException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const NoMoreEntriesException& val);
 
-  void __set_ouch2(const UnknownScanner& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const UnknownScanner& val);
 
-  void __set_ouch3(const AccumuloSecurityException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_nextK_result & rhs) const
   {
@@ -9790,18 +9532,17 @@
 
 typedef struct _AccumuloProxy_nextK_presult__isset {
   _AccumuloProxy_nextK_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_nextK_presult__isset;
 
 class AccumuloProxy_nextK_presult {
  public:
 
 
-  virtual ~AccumuloProxy_nextK_presult() throw() {}
-
+  virtual ~AccumuloProxy_nextK_presult() throw();
   ScanResult* success;
   NoMoreEntriesException ouch1;
   UnknownScanner ouch2;
@@ -9815,24 +9556,23 @@
 
 typedef struct _AccumuloProxy_closeScanner_args__isset {
   _AccumuloProxy_closeScanner_args__isset() : scanner(false) {}
-  bool scanner;
+  bool scanner :1;
 } _AccumuloProxy_closeScanner_args__isset;
 
 class AccumuloProxy_closeScanner_args {
  public:
 
+  AccumuloProxy_closeScanner_args(const AccumuloProxy_closeScanner_args&);
+  AccumuloProxy_closeScanner_args& operator=(const AccumuloProxy_closeScanner_args&);
   AccumuloProxy_closeScanner_args() : scanner() {
   }
 
-  virtual ~AccumuloProxy_closeScanner_args() throw() {}
-
+  virtual ~AccumuloProxy_closeScanner_args() throw();
   std::string scanner;
 
   _AccumuloProxy_closeScanner_args__isset __isset;
 
-  void __set_scanner(const std::string& val) {
-    scanner = val;
-  }
+  void __set_scanner(const std::string& val);
 
   bool operator == (const AccumuloProxy_closeScanner_args & rhs) const
   {
@@ -9856,8 +9596,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_closeScanner_pargs() throw() {}
-
+  virtual ~AccumuloProxy_closeScanner_pargs() throw();
   const std::string* scanner;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -9866,24 +9605,23 @@
 
 typedef struct _AccumuloProxy_closeScanner_result__isset {
   _AccumuloProxy_closeScanner_result__isset() : ouch1(false) {}
-  bool ouch1;
+  bool ouch1 :1;
 } _AccumuloProxy_closeScanner_result__isset;
 
 class AccumuloProxy_closeScanner_result {
  public:
 
+  AccumuloProxy_closeScanner_result(const AccumuloProxy_closeScanner_result&);
+  AccumuloProxy_closeScanner_result& operator=(const AccumuloProxy_closeScanner_result&);
   AccumuloProxy_closeScanner_result() {
   }
 
-  virtual ~AccumuloProxy_closeScanner_result() throw() {}
-
+  virtual ~AccumuloProxy_closeScanner_result() throw();
   UnknownScanner ouch1;
 
   _AccumuloProxy_closeScanner_result__isset __isset;
 
-  void __set_ouch1(const UnknownScanner& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const UnknownScanner& val);
 
   bool operator == (const AccumuloProxy_closeScanner_result & rhs) const
   {
@@ -9904,15 +9642,14 @@
 
 typedef struct _AccumuloProxy_closeScanner_presult__isset {
   _AccumuloProxy_closeScanner_presult__isset() : ouch1(false) {}
-  bool ouch1;
+  bool ouch1 :1;
 } _AccumuloProxy_closeScanner_presult__isset;
 
 class AccumuloProxy_closeScanner_presult {
  public:
 
 
-  virtual ~AccumuloProxy_closeScanner_presult() throw() {}
-
+  virtual ~AccumuloProxy_closeScanner_presult() throw();
   UnknownScanner ouch1;
 
   _AccumuloProxy_closeScanner_presult__isset __isset;
@@ -9923,36 +9660,31 @@
 
 typedef struct _AccumuloProxy_updateAndFlush_args__isset {
   _AccumuloProxy_updateAndFlush_args__isset() : login(false), tableName(false), cells(false) {}
-  bool login;
-  bool tableName;
-  bool cells;
+  bool login :1;
+  bool tableName :1;
+  bool cells :1;
 } _AccumuloProxy_updateAndFlush_args__isset;
 
 class AccumuloProxy_updateAndFlush_args {
  public:
 
+  AccumuloProxy_updateAndFlush_args(const AccumuloProxy_updateAndFlush_args&);
+  AccumuloProxy_updateAndFlush_args& operator=(const AccumuloProxy_updateAndFlush_args&);
   AccumuloProxy_updateAndFlush_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_updateAndFlush_args() throw() {}
-
+  virtual ~AccumuloProxy_updateAndFlush_args() throw();
   std::string login;
   std::string tableName;
   std::map<std::string, std::vector<ColumnUpdate> >  cells;
 
   _AccumuloProxy_updateAndFlush_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_cells(const std::map<std::string, std::vector<ColumnUpdate> > & val) {
-    cells = val;
-  }
+  void __set_cells(const std::map<std::string, std::vector<ColumnUpdate> > & val);
 
   bool operator == (const AccumuloProxy_updateAndFlush_args & rhs) const
   {
@@ -9980,8 +9712,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_updateAndFlush_pargs() throw() {}
-
+  virtual ~AccumuloProxy_updateAndFlush_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::map<std::string, std::vector<ColumnUpdate> > * cells;
@@ -9992,20 +9723,21 @@
 
 typedef struct _AccumuloProxy_updateAndFlush_result__isset {
   _AccumuloProxy_updateAndFlush_result__isset() : outch1(false), ouch2(false), ouch3(false), ouch4(false) {}
-  bool outch1;
-  bool ouch2;
-  bool ouch3;
-  bool ouch4;
+  bool outch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
 } _AccumuloProxy_updateAndFlush_result__isset;
 
 class AccumuloProxy_updateAndFlush_result {
  public:
 
+  AccumuloProxy_updateAndFlush_result(const AccumuloProxy_updateAndFlush_result&);
+  AccumuloProxy_updateAndFlush_result& operator=(const AccumuloProxy_updateAndFlush_result&);
   AccumuloProxy_updateAndFlush_result() {
   }
 
-  virtual ~AccumuloProxy_updateAndFlush_result() throw() {}
-
+  virtual ~AccumuloProxy_updateAndFlush_result() throw();
   AccumuloException outch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -10013,21 +9745,13 @@
 
   _AccumuloProxy_updateAndFlush_result__isset __isset;
 
-  void __set_outch1(const AccumuloException& val) {
-    outch1 = val;
-  }
+  void __set_outch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
-  void __set_ouch4(const MutationsRejectedException& val) {
-    ouch4 = val;
-  }
+  void __set_ouch4(const MutationsRejectedException& val);
 
   bool operator == (const AccumuloProxy_updateAndFlush_result & rhs) const
   {
@@ -10054,18 +9778,17 @@
 
 typedef struct _AccumuloProxy_updateAndFlush_presult__isset {
   _AccumuloProxy_updateAndFlush_presult__isset() : outch1(false), ouch2(false), ouch3(false), ouch4(false) {}
-  bool outch1;
-  bool ouch2;
-  bool ouch3;
-  bool ouch4;
+  bool outch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
 } _AccumuloProxy_updateAndFlush_presult__isset;
 
 class AccumuloProxy_updateAndFlush_presult {
  public:
 
 
-  virtual ~AccumuloProxy_updateAndFlush_presult() throw() {}
-
+  virtual ~AccumuloProxy_updateAndFlush_presult() throw();
   AccumuloException outch1;
   AccumuloSecurityException ouch2;
   TableNotFoundException ouch3;
@@ -10079,36 +9802,31 @@
 
 typedef struct _AccumuloProxy_createWriter_args__isset {
   _AccumuloProxy_createWriter_args__isset() : login(false), tableName(false), opts(false) {}
-  bool login;
-  bool tableName;
-  bool opts;
+  bool login :1;
+  bool tableName :1;
+  bool opts :1;
 } _AccumuloProxy_createWriter_args__isset;
 
 class AccumuloProxy_createWriter_args {
  public:
 
+  AccumuloProxy_createWriter_args(const AccumuloProxy_createWriter_args&);
+  AccumuloProxy_createWriter_args& operator=(const AccumuloProxy_createWriter_args&);
   AccumuloProxy_createWriter_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_createWriter_args() throw() {}
-
+  virtual ~AccumuloProxy_createWriter_args() throw();
   std::string login;
   std::string tableName;
   WriterOptions opts;
 
   _AccumuloProxy_createWriter_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_opts(const WriterOptions& val) {
-    opts = val;
-  }
+  void __set_opts(const WriterOptions& val);
 
   bool operator == (const AccumuloProxy_createWriter_args & rhs) const
   {
@@ -10136,8 +9854,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_createWriter_pargs() throw() {}
-
+  virtual ~AccumuloProxy_createWriter_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const WriterOptions* opts;
@@ -10148,20 +9865,21 @@
 
 typedef struct _AccumuloProxy_createWriter_result__isset {
   _AccumuloProxy_createWriter_result__isset() : success(false), outch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool outch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool outch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_createWriter_result__isset;
 
 class AccumuloProxy_createWriter_result {
  public:
 
+  AccumuloProxy_createWriter_result(const AccumuloProxy_createWriter_result&);
+  AccumuloProxy_createWriter_result& operator=(const AccumuloProxy_createWriter_result&);
   AccumuloProxy_createWriter_result() : success() {
   }
 
-  virtual ~AccumuloProxy_createWriter_result() throw() {}
-
+  virtual ~AccumuloProxy_createWriter_result() throw();
   std::string success;
   AccumuloException outch1;
   AccumuloSecurityException ouch2;
@@ -10169,21 +9887,13 @@
 
   _AccumuloProxy_createWriter_result__isset __isset;
 
-  void __set_success(const std::string& val) {
-    success = val;
-  }
+  void __set_success(const std::string& val);
 
-  void __set_outch1(const AccumuloException& val) {
-    outch1 = val;
-  }
+  void __set_outch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_createWriter_result & rhs) const
   {
@@ -10210,18 +9920,17 @@
 
 typedef struct _AccumuloProxy_createWriter_presult__isset {
   _AccumuloProxy_createWriter_presult__isset() : success(false), outch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool outch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool outch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_createWriter_presult__isset;
 
 class AccumuloProxy_createWriter_presult {
  public:
 
 
-  virtual ~AccumuloProxy_createWriter_presult() throw() {}
-
+  virtual ~AccumuloProxy_createWriter_presult() throw();
   std::string* success;
   AccumuloException outch1;
   AccumuloSecurityException ouch2;
@@ -10235,30 +9944,27 @@
 
 typedef struct _AccumuloProxy_update_args__isset {
   _AccumuloProxy_update_args__isset() : writer(false), cells(false) {}
-  bool writer;
-  bool cells;
+  bool writer :1;
+  bool cells :1;
 } _AccumuloProxy_update_args__isset;
 
 class AccumuloProxy_update_args {
  public:
 
+  AccumuloProxy_update_args(const AccumuloProxy_update_args&);
+  AccumuloProxy_update_args& operator=(const AccumuloProxy_update_args&);
   AccumuloProxy_update_args() : writer() {
   }
 
-  virtual ~AccumuloProxy_update_args() throw() {}
-
+  virtual ~AccumuloProxy_update_args() throw();
   std::string writer;
   std::map<std::string, std::vector<ColumnUpdate> >  cells;
 
   _AccumuloProxy_update_args__isset __isset;
 
-  void __set_writer(const std::string& val) {
-    writer = val;
-  }
+  void __set_writer(const std::string& val);
 
-  void __set_cells(const std::map<std::string, std::vector<ColumnUpdate> > & val) {
-    cells = val;
-  }
+  void __set_cells(const std::map<std::string, std::vector<ColumnUpdate> > & val);
 
   bool operator == (const AccumuloProxy_update_args & rhs) const
   {
@@ -10284,8 +9990,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_update_pargs() throw() {}
-
+  virtual ~AccumuloProxy_update_pargs() throw();
   const std::string* writer;
   const std::map<std::string, std::vector<ColumnUpdate> > * cells;
 
@@ -10295,24 +10000,23 @@
 
 typedef struct _AccumuloProxy_flush_args__isset {
   _AccumuloProxy_flush_args__isset() : writer(false) {}
-  bool writer;
+  bool writer :1;
 } _AccumuloProxy_flush_args__isset;
 
 class AccumuloProxy_flush_args {
  public:
 
+  AccumuloProxy_flush_args(const AccumuloProxy_flush_args&);
+  AccumuloProxy_flush_args& operator=(const AccumuloProxy_flush_args&);
   AccumuloProxy_flush_args() : writer() {
   }
 
-  virtual ~AccumuloProxy_flush_args() throw() {}
-
+  virtual ~AccumuloProxy_flush_args() throw();
   std::string writer;
 
   _AccumuloProxy_flush_args__isset __isset;
 
-  void __set_writer(const std::string& val) {
-    writer = val;
-  }
+  void __set_writer(const std::string& val);
 
   bool operator == (const AccumuloProxy_flush_args & rhs) const
   {
@@ -10336,8 +10040,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_flush_pargs() throw() {}
-
+  virtual ~AccumuloProxy_flush_pargs() throw();
   const std::string* writer;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -10346,30 +10049,27 @@
 
 typedef struct _AccumuloProxy_flush_result__isset {
   _AccumuloProxy_flush_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_flush_result__isset;
 
 class AccumuloProxy_flush_result {
  public:
 
+  AccumuloProxy_flush_result(const AccumuloProxy_flush_result&);
+  AccumuloProxy_flush_result& operator=(const AccumuloProxy_flush_result&);
   AccumuloProxy_flush_result() {
   }
 
-  virtual ~AccumuloProxy_flush_result() throw() {}
-
+  virtual ~AccumuloProxy_flush_result() throw();
   UnknownWriter ouch1;
   MutationsRejectedException ouch2;
 
   _AccumuloProxy_flush_result__isset __isset;
 
-  void __set_ouch1(const UnknownWriter& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const UnknownWriter& val);
 
-  void __set_ouch2(const MutationsRejectedException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const MutationsRejectedException& val);
 
   bool operator == (const AccumuloProxy_flush_result & rhs) const
   {
@@ -10392,16 +10092,15 @@
 
 typedef struct _AccumuloProxy_flush_presult__isset {
   _AccumuloProxy_flush_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_flush_presult__isset;
 
 class AccumuloProxy_flush_presult {
  public:
 
 
-  virtual ~AccumuloProxy_flush_presult() throw() {}
-
+  virtual ~AccumuloProxy_flush_presult() throw();
   UnknownWriter ouch1;
   MutationsRejectedException ouch2;
 
@@ -10413,24 +10112,23 @@
 
 typedef struct _AccumuloProxy_closeWriter_args__isset {
   _AccumuloProxy_closeWriter_args__isset() : writer(false) {}
-  bool writer;
+  bool writer :1;
 } _AccumuloProxy_closeWriter_args__isset;
 
 class AccumuloProxy_closeWriter_args {
  public:
 
+  AccumuloProxy_closeWriter_args(const AccumuloProxy_closeWriter_args&);
+  AccumuloProxy_closeWriter_args& operator=(const AccumuloProxy_closeWriter_args&);
   AccumuloProxy_closeWriter_args() : writer() {
   }
 
-  virtual ~AccumuloProxy_closeWriter_args() throw() {}
-
+  virtual ~AccumuloProxy_closeWriter_args() throw();
   std::string writer;
 
   _AccumuloProxy_closeWriter_args__isset __isset;
 
-  void __set_writer(const std::string& val) {
-    writer = val;
-  }
+  void __set_writer(const std::string& val);
 
   bool operator == (const AccumuloProxy_closeWriter_args & rhs) const
   {
@@ -10454,8 +10152,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_closeWriter_pargs() throw() {}
-
+  virtual ~AccumuloProxy_closeWriter_pargs() throw();
   const std::string* writer;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -10464,30 +10161,27 @@
 
 typedef struct _AccumuloProxy_closeWriter_result__isset {
   _AccumuloProxy_closeWriter_result__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_closeWriter_result__isset;
 
 class AccumuloProxy_closeWriter_result {
  public:
 
+  AccumuloProxy_closeWriter_result(const AccumuloProxy_closeWriter_result&);
+  AccumuloProxy_closeWriter_result& operator=(const AccumuloProxy_closeWriter_result&);
   AccumuloProxy_closeWriter_result() {
   }
 
-  virtual ~AccumuloProxy_closeWriter_result() throw() {}
-
+  virtual ~AccumuloProxy_closeWriter_result() throw();
   UnknownWriter ouch1;
   MutationsRejectedException ouch2;
 
   _AccumuloProxy_closeWriter_result__isset __isset;
 
-  void __set_ouch1(const UnknownWriter& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const UnknownWriter& val);
 
-  void __set_ouch2(const MutationsRejectedException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const MutationsRejectedException& val);
 
   bool operator == (const AccumuloProxy_closeWriter_result & rhs) const
   {
@@ -10510,16 +10204,15 @@
 
 typedef struct _AccumuloProxy_closeWriter_presult__isset {
   _AccumuloProxy_closeWriter_presult__isset() : ouch1(false), ouch2(false) {}
-  bool ouch1;
-  bool ouch2;
+  bool ouch1 :1;
+  bool ouch2 :1;
 } _AccumuloProxy_closeWriter_presult__isset;
 
 class AccumuloProxy_closeWriter_presult {
  public:
 
 
-  virtual ~AccumuloProxy_closeWriter_presult() throw() {}
-
+  virtual ~AccumuloProxy_closeWriter_presult() throw();
   UnknownWriter ouch1;
   MutationsRejectedException ouch2;
 
@@ -10531,20 +10224,21 @@
 
 typedef struct _AccumuloProxy_updateRowConditionally_args__isset {
   _AccumuloProxy_updateRowConditionally_args__isset() : login(false), tableName(false), row(false), updates(false) {}
-  bool login;
-  bool tableName;
-  bool row;
-  bool updates;
+  bool login :1;
+  bool tableName :1;
+  bool row :1;
+  bool updates :1;
 } _AccumuloProxy_updateRowConditionally_args__isset;
 
 class AccumuloProxy_updateRowConditionally_args {
  public:
 
+  AccumuloProxy_updateRowConditionally_args(const AccumuloProxy_updateRowConditionally_args&);
+  AccumuloProxy_updateRowConditionally_args& operator=(const AccumuloProxy_updateRowConditionally_args&);
   AccumuloProxy_updateRowConditionally_args() : login(), tableName(), row() {
   }
 
-  virtual ~AccumuloProxy_updateRowConditionally_args() throw() {}
-
+  virtual ~AccumuloProxy_updateRowConditionally_args() throw();
   std::string login;
   std::string tableName;
   std::string row;
@@ -10552,21 +10246,13 @@
 
   _AccumuloProxy_updateRowConditionally_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_row(const std::string& val) {
-    row = val;
-  }
+  void __set_row(const std::string& val);
 
-  void __set_updates(const ConditionalUpdates& val) {
-    updates = val;
-  }
+  void __set_updates(const ConditionalUpdates& val);
 
   bool operator == (const AccumuloProxy_updateRowConditionally_args & rhs) const
   {
@@ -10596,8 +10282,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_updateRowConditionally_pargs() throw() {}
-
+  virtual ~AccumuloProxy_updateRowConditionally_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const std::string* row;
@@ -10609,20 +10294,21 @@
 
 typedef struct _AccumuloProxy_updateRowConditionally_result__isset {
   _AccumuloProxy_updateRowConditionally_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_updateRowConditionally_result__isset;
 
 class AccumuloProxy_updateRowConditionally_result {
  public:
 
+  AccumuloProxy_updateRowConditionally_result(const AccumuloProxy_updateRowConditionally_result&);
+  AccumuloProxy_updateRowConditionally_result& operator=(const AccumuloProxy_updateRowConditionally_result&);
   AccumuloProxy_updateRowConditionally_result() : success((ConditionalStatus::type)0) {
   }
 
-  virtual ~AccumuloProxy_updateRowConditionally_result() throw() {}
-
+  virtual ~AccumuloProxy_updateRowConditionally_result() throw();
   ConditionalStatus::type success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -10630,21 +10316,13 @@
 
   _AccumuloProxy_updateRowConditionally_result__isset __isset;
 
-  void __set_success(const ConditionalStatus::type val) {
-    success = val;
-  }
+  void __set_success(const ConditionalStatus::type val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_updateRowConditionally_result & rhs) const
   {
@@ -10671,18 +10349,17 @@
 
 typedef struct _AccumuloProxy_updateRowConditionally_presult__isset {
   _AccumuloProxy_updateRowConditionally_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_updateRowConditionally_presult__isset;
 
 class AccumuloProxy_updateRowConditionally_presult {
  public:
 
 
-  virtual ~AccumuloProxy_updateRowConditionally_presult() throw() {}
-
+  virtual ~AccumuloProxy_updateRowConditionally_presult() throw();
   ConditionalStatus::type* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -10696,36 +10373,31 @@
 
 typedef struct _AccumuloProxy_createConditionalWriter_args__isset {
   _AccumuloProxy_createConditionalWriter_args__isset() : login(false), tableName(false), options(false) {}
-  bool login;
-  bool tableName;
-  bool options;
+  bool login :1;
+  bool tableName :1;
+  bool options :1;
 } _AccumuloProxy_createConditionalWriter_args__isset;
 
 class AccumuloProxy_createConditionalWriter_args {
  public:
 
+  AccumuloProxy_createConditionalWriter_args(const AccumuloProxy_createConditionalWriter_args&);
+  AccumuloProxy_createConditionalWriter_args& operator=(const AccumuloProxy_createConditionalWriter_args&);
   AccumuloProxy_createConditionalWriter_args() : login(), tableName() {
   }
 
-  virtual ~AccumuloProxy_createConditionalWriter_args() throw() {}
-
+  virtual ~AccumuloProxy_createConditionalWriter_args() throw();
   std::string login;
   std::string tableName;
   ConditionalWriterOptions options;
 
   _AccumuloProxy_createConditionalWriter_args__isset __isset;
 
-  void __set_login(const std::string& val) {
-    login = val;
-  }
+  void __set_login(const std::string& val);
 
-  void __set_tableName(const std::string& val) {
-    tableName = val;
-  }
+  void __set_tableName(const std::string& val);
 
-  void __set_options(const ConditionalWriterOptions& val) {
-    options = val;
-  }
+  void __set_options(const ConditionalWriterOptions& val);
 
   bool operator == (const AccumuloProxy_createConditionalWriter_args & rhs) const
   {
@@ -10753,8 +10425,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_createConditionalWriter_pargs() throw() {}
-
+  virtual ~AccumuloProxy_createConditionalWriter_pargs() throw();
   const std::string* login;
   const std::string* tableName;
   const ConditionalWriterOptions* options;
@@ -10765,20 +10436,21 @@
 
 typedef struct _AccumuloProxy_createConditionalWriter_result__isset {
   _AccumuloProxy_createConditionalWriter_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_createConditionalWriter_result__isset;
 
 class AccumuloProxy_createConditionalWriter_result {
  public:
 
+  AccumuloProxy_createConditionalWriter_result(const AccumuloProxy_createConditionalWriter_result&);
+  AccumuloProxy_createConditionalWriter_result& operator=(const AccumuloProxy_createConditionalWriter_result&);
   AccumuloProxy_createConditionalWriter_result() : success() {
   }
 
-  virtual ~AccumuloProxy_createConditionalWriter_result() throw() {}
-
+  virtual ~AccumuloProxy_createConditionalWriter_result() throw();
   std::string success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -10786,21 +10458,13 @@
 
   _AccumuloProxy_createConditionalWriter_result__isset __isset;
 
-  void __set_success(const std::string& val) {
-    success = val;
-  }
+  void __set_success(const std::string& val);
 
-  void __set_ouch1(const AccumuloException& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const AccumuloException& val);
 
-  void __set_ouch2(const AccumuloSecurityException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloSecurityException& val);
 
-  void __set_ouch3(const TableNotFoundException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const TableNotFoundException& val);
 
   bool operator == (const AccumuloProxy_createConditionalWriter_result & rhs) const
   {
@@ -10827,18 +10491,17 @@
 
 typedef struct _AccumuloProxy_createConditionalWriter_presult__isset {
   _AccumuloProxy_createConditionalWriter_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_createConditionalWriter_presult__isset;
 
 class AccumuloProxy_createConditionalWriter_presult {
  public:
 
 
-  virtual ~AccumuloProxy_createConditionalWriter_presult() throw() {}
-
+  virtual ~AccumuloProxy_createConditionalWriter_presult() throw();
   std::string* success;
   AccumuloException ouch1;
   AccumuloSecurityException ouch2;
@@ -10852,30 +10515,27 @@
 
 typedef struct _AccumuloProxy_updateRowsConditionally_args__isset {
   _AccumuloProxy_updateRowsConditionally_args__isset() : conditionalWriter(false), updates(false) {}
-  bool conditionalWriter;
-  bool updates;
+  bool conditionalWriter :1;
+  bool updates :1;
 } _AccumuloProxy_updateRowsConditionally_args__isset;
 
 class AccumuloProxy_updateRowsConditionally_args {
  public:
 
+  AccumuloProxy_updateRowsConditionally_args(const AccumuloProxy_updateRowsConditionally_args&);
+  AccumuloProxy_updateRowsConditionally_args& operator=(const AccumuloProxy_updateRowsConditionally_args&);
   AccumuloProxy_updateRowsConditionally_args() : conditionalWriter() {
   }
 
-  virtual ~AccumuloProxy_updateRowsConditionally_args() throw() {}
-
+  virtual ~AccumuloProxy_updateRowsConditionally_args() throw();
   std::string conditionalWriter;
   std::map<std::string, ConditionalUpdates>  updates;
 
   _AccumuloProxy_updateRowsConditionally_args__isset __isset;
 
-  void __set_conditionalWriter(const std::string& val) {
-    conditionalWriter = val;
-  }
+  void __set_conditionalWriter(const std::string& val);
 
-  void __set_updates(const std::map<std::string, ConditionalUpdates> & val) {
-    updates = val;
-  }
+  void __set_updates(const std::map<std::string, ConditionalUpdates> & val);
 
   bool operator == (const AccumuloProxy_updateRowsConditionally_args & rhs) const
   {
@@ -10901,8 +10561,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_updateRowsConditionally_pargs() throw() {}
-
+  virtual ~AccumuloProxy_updateRowsConditionally_pargs() throw();
   const std::string* conditionalWriter;
   const std::map<std::string, ConditionalUpdates> * updates;
 
@@ -10912,20 +10571,21 @@
 
 typedef struct _AccumuloProxy_updateRowsConditionally_result__isset {
   _AccumuloProxy_updateRowsConditionally_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_updateRowsConditionally_result__isset;
 
 class AccumuloProxy_updateRowsConditionally_result {
  public:
 
+  AccumuloProxy_updateRowsConditionally_result(const AccumuloProxy_updateRowsConditionally_result&);
+  AccumuloProxy_updateRowsConditionally_result& operator=(const AccumuloProxy_updateRowsConditionally_result&);
   AccumuloProxy_updateRowsConditionally_result() {
   }
 
-  virtual ~AccumuloProxy_updateRowsConditionally_result() throw() {}
-
+  virtual ~AccumuloProxy_updateRowsConditionally_result() throw();
   std::map<std::string, ConditionalStatus::type>  success;
   UnknownWriter ouch1;
   AccumuloException ouch2;
@@ -10933,21 +10593,13 @@
 
   _AccumuloProxy_updateRowsConditionally_result__isset __isset;
 
-  void __set_success(const std::map<std::string, ConditionalStatus::type> & val) {
-    success = val;
-  }
+  void __set_success(const std::map<std::string, ConditionalStatus::type> & val);
 
-  void __set_ouch1(const UnknownWriter& val) {
-    ouch1 = val;
-  }
+  void __set_ouch1(const UnknownWriter& val);
 
-  void __set_ouch2(const AccumuloException& val) {
-    ouch2 = val;
-  }
+  void __set_ouch2(const AccumuloException& val);
 
-  void __set_ouch3(const AccumuloSecurityException& val) {
-    ouch3 = val;
-  }
+  void __set_ouch3(const AccumuloSecurityException& val);
 
   bool operator == (const AccumuloProxy_updateRowsConditionally_result & rhs) const
   {
@@ -10974,18 +10626,17 @@
 
 typedef struct _AccumuloProxy_updateRowsConditionally_presult__isset {
   _AccumuloProxy_updateRowsConditionally_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
-  bool success;
-  bool ouch1;
-  bool ouch2;
-  bool ouch3;
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
 } _AccumuloProxy_updateRowsConditionally_presult__isset;
 
 class AccumuloProxy_updateRowsConditionally_presult {
  public:
 
 
-  virtual ~AccumuloProxy_updateRowsConditionally_presult() throw() {}
-
+  virtual ~AccumuloProxy_updateRowsConditionally_presult() throw();
   std::map<std::string, ConditionalStatus::type> * success;
   UnknownWriter ouch1;
   AccumuloException ouch2;
@@ -10999,24 +10650,23 @@
 
 typedef struct _AccumuloProxy_closeConditionalWriter_args__isset {
   _AccumuloProxy_closeConditionalWriter_args__isset() : conditionalWriter(false) {}
-  bool conditionalWriter;
+  bool conditionalWriter :1;
 } _AccumuloProxy_closeConditionalWriter_args__isset;
 
 class AccumuloProxy_closeConditionalWriter_args {
  public:
 
+  AccumuloProxy_closeConditionalWriter_args(const AccumuloProxy_closeConditionalWriter_args&);
+  AccumuloProxy_closeConditionalWriter_args& operator=(const AccumuloProxy_closeConditionalWriter_args&);
   AccumuloProxy_closeConditionalWriter_args() : conditionalWriter() {
   }
 
-  virtual ~AccumuloProxy_closeConditionalWriter_args() throw() {}
-
+  virtual ~AccumuloProxy_closeConditionalWriter_args() throw();
   std::string conditionalWriter;
 
   _AccumuloProxy_closeConditionalWriter_args__isset __isset;
 
-  void __set_conditionalWriter(const std::string& val) {
-    conditionalWriter = val;
-  }
+  void __set_conditionalWriter(const std::string& val);
 
   bool operator == (const AccumuloProxy_closeConditionalWriter_args & rhs) const
   {
@@ -11040,8 +10690,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_closeConditionalWriter_pargs() throw() {}
-
+  virtual ~AccumuloProxy_closeConditionalWriter_pargs() throw();
   const std::string* conditionalWriter;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -11052,11 +10701,12 @@
 class AccumuloProxy_closeConditionalWriter_result {
  public:
 
+  AccumuloProxy_closeConditionalWriter_result(const AccumuloProxy_closeConditionalWriter_result&);
+  AccumuloProxy_closeConditionalWriter_result& operator=(const AccumuloProxy_closeConditionalWriter_result&);
   AccumuloProxy_closeConditionalWriter_result() {
   }
 
-  virtual ~AccumuloProxy_closeConditionalWriter_result() throw() {}
-
+  virtual ~AccumuloProxy_closeConditionalWriter_result() throw();
 
   bool operator == (const AccumuloProxy_closeConditionalWriter_result & /* rhs */) const
   {
@@ -11078,8 +10728,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_closeConditionalWriter_presult() throw() {}
-
+  virtual ~AccumuloProxy_closeConditionalWriter_presult() throw();
 
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
 
@@ -11087,24 +10736,23 @@
 
 typedef struct _AccumuloProxy_getRowRange_args__isset {
   _AccumuloProxy_getRowRange_args__isset() : row(false) {}
-  bool row;
+  bool row :1;
 } _AccumuloProxy_getRowRange_args__isset;
 
 class AccumuloProxy_getRowRange_args {
  public:
 
+  AccumuloProxy_getRowRange_args(const AccumuloProxy_getRowRange_args&);
+  AccumuloProxy_getRowRange_args& operator=(const AccumuloProxy_getRowRange_args&);
   AccumuloProxy_getRowRange_args() : row() {
   }
 
-  virtual ~AccumuloProxy_getRowRange_args() throw() {}
-
+  virtual ~AccumuloProxy_getRowRange_args() throw();
   std::string row;
 
   _AccumuloProxy_getRowRange_args__isset __isset;
 
-  void __set_row(const std::string& val) {
-    row = val;
-  }
+  void __set_row(const std::string& val);
 
   bool operator == (const AccumuloProxy_getRowRange_args & rhs) const
   {
@@ -11128,8 +10776,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getRowRange_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getRowRange_pargs() throw();
   const std::string* row;
 
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
@@ -11138,24 +10785,23 @@
 
 typedef struct _AccumuloProxy_getRowRange_result__isset {
   _AccumuloProxy_getRowRange_result__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_getRowRange_result__isset;
 
 class AccumuloProxy_getRowRange_result {
  public:
 
+  AccumuloProxy_getRowRange_result(const AccumuloProxy_getRowRange_result&);
+  AccumuloProxy_getRowRange_result& operator=(const AccumuloProxy_getRowRange_result&);
   AccumuloProxy_getRowRange_result() {
   }
 
-  virtual ~AccumuloProxy_getRowRange_result() throw() {}
-
+  virtual ~AccumuloProxy_getRowRange_result() throw();
   Range success;
 
   _AccumuloProxy_getRowRange_result__isset __isset;
 
-  void __set_success(const Range& val) {
-    success = val;
-  }
+  void __set_success(const Range& val);
 
   bool operator == (const AccumuloProxy_getRowRange_result & rhs) const
   {
@@ -11176,15 +10822,14 @@
 
 typedef struct _AccumuloProxy_getRowRange_presult__isset {
   _AccumuloProxy_getRowRange_presult__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_getRowRange_presult__isset;
 
 class AccumuloProxy_getRowRange_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getRowRange_presult() throw() {}
-
+  virtual ~AccumuloProxy_getRowRange_presult() throw();
   Range* success;
 
   _AccumuloProxy_getRowRange_presult__isset __isset;
@@ -11195,30 +10840,27 @@
 
 typedef struct _AccumuloProxy_getFollowing_args__isset {
   _AccumuloProxy_getFollowing_args__isset() : key(false), part(false) {}
-  bool key;
-  bool part;
+  bool key :1;
+  bool part :1;
 } _AccumuloProxy_getFollowing_args__isset;
 
 class AccumuloProxy_getFollowing_args {
  public:
 
+  AccumuloProxy_getFollowing_args(const AccumuloProxy_getFollowing_args&);
+  AccumuloProxy_getFollowing_args& operator=(const AccumuloProxy_getFollowing_args&);
   AccumuloProxy_getFollowing_args() : part((PartialKey::type)0) {
   }
 
-  virtual ~AccumuloProxy_getFollowing_args() throw() {}
-
+  virtual ~AccumuloProxy_getFollowing_args() throw();
   Key key;
   PartialKey::type part;
 
   _AccumuloProxy_getFollowing_args__isset __isset;
 
-  void __set_key(const Key& val) {
-    key = val;
-  }
+  void __set_key(const Key& val);
 
-  void __set_part(const PartialKey::type val) {
-    part = val;
-  }
+  void __set_part(const PartialKey::type val);
 
   bool operator == (const AccumuloProxy_getFollowing_args & rhs) const
   {
@@ -11244,8 +10886,7 @@
  public:
 
 
-  virtual ~AccumuloProxy_getFollowing_pargs() throw() {}
-
+  virtual ~AccumuloProxy_getFollowing_pargs() throw();
   const Key* key;
   const PartialKey::type* part;
 
@@ -11255,24 +10896,23 @@
 
 typedef struct _AccumuloProxy_getFollowing_result__isset {
   _AccumuloProxy_getFollowing_result__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_getFollowing_result__isset;
 
 class AccumuloProxy_getFollowing_result {
  public:
 
+  AccumuloProxy_getFollowing_result(const AccumuloProxy_getFollowing_result&);
+  AccumuloProxy_getFollowing_result& operator=(const AccumuloProxy_getFollowing_result&);
   AccumuloProxy_getFollowing_result() {
   }
 
-  virtual ~AccumuloProxy_getFollowing_result() throw() {}
-
+  virtual ~AccumuloProxy_getFollowing_result() throw();
   Key success;
 
   _AccumuloProxy_getFollowing_result__isset __isset;
 
-  void __set_success(const Key& val) {
-    success = val;
-  }
+  void __set_success(const Key& val);
 
   bool operator == (const AccumuloProxy_getFollowing_result & rhs) const
   {
@@ -11293,15 +10933,14 @@
 
 typedef struct _AccumuloProxy_getFollowing_presult__isset {
   _AccumuloProxy_getFollowing_presult__isset() : success(false) {}
-  bool success;
+  bool success :1;
 } _AccumuloProxy_getFollowing_presult__isset;
 
 class AccumuloProxy_getFollowing_presult {
  public:
 
 
-  virtual ~AccumuloProxy_getFollowing_presult() throw() {}
-
+  virtual ~AccumuloProxy_getFollowing_presult() throw();
   Key* success;
 
   _AccumuloProxy_getFollowing_presult__isset __isset;
@@ -11310,20 +10949,2657 @@
 
 };
 
+
+class AccumuloProxy_systemNamespace_args {
+ public:
+
+  AccumuloProxy_systemNamespace_args(const AccumuloProxy_systemNamespace_args&);
+  AccumuloProxy_systemNamespace_args& operator=(const AccumuloProxy_systemNamespace_args&);
+  AccumuloProxy_systemNamespace_args() {
+  }
+
+  virtual ~AccumuloProxy_systemNamespace_args() throw();
+
+  bool operator == (const AccumuloProxy_systemNamespace_args & /* rhs */) const
+  {
+    return true;
+  }
+  bool operator != (const AccumuloProxy_systemNamespace_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_systemNamespace_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_systemNamespace_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_systemNamespace_pargs() throw();
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_systemNamespace_result__isset {
+  _AccumuloProxy_systemNamespace_result__isset() : success(false) {}
+  bool success :1;
+} _AccumuloProxy_systemNamespace_result__isset;
+
+class AccumuloProxy_systemNamespace_result {
+ public:
+
+  AccumuloProxy_systemNamespace_result(const AccumuloProxy_systemNamespace_result&);
+  AccumuloProxy_systemNamespace_result& operator=(const AccumuloProxy_systemNamespace_result&);
+  AccumuloProxy_systemNamespace_result() : success() {
+  }
+
+  virtual ~AccumuloProxy_systemNamespace_result() throw();
+  std::string success;
+
+  _AccumuloProxy_systemNamespace_result__isset __isset;
+
+  void __set_success(const std::string& val);
+
+  bool operator == (const AccumuloProxy_systemNamespace_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_systemNamespace_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_systemNamespace_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_systemNamespace_presult__isset {
+  _AccumuloProxy_systemNamespace_presult__isset() : success(false) {}
+  bool success :1;
+} _AccumuloProxy_systemNamespace_presult__isset;
+
+class AccumuloProxy_systemNamespace_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_systemNamespace_presult() throw();
+  std::string* success;
+
+  _AccumuloProxy_systemNamespace_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+
+class AccumuloProxy_defaultNamespace_args {
+ public:
+
+  AccumuloProxy_defaultNamespace_args(const AccumuloProxy_defaultNamespace_args&);
+  AccumuloProxy_defaultNamespace_args& operator=(const AccumuloProxy_defaultNamespace_args&);
+  AccumuloProxy_defaultNamespace_args() {
+  }
+
+  virtual ~AccumuloProxy_defaultNamespace_args() throw();
+
+  bool operator == (const AccumuloProxy_defaultNamespace_args & /* rhs */) const
+  {
+    return true;
+  }
+  bool operator != (const AccumuloProxy_defaultNamespace_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_defaultNamespace_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_defaultNamespace_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_defaultNamespace_pargs() throw();
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_defaultNamespace_result__isset {
+  _AccumuloProxy_defaultNamespace_result__isset() : success(false) {}
+  bool success :1;
+} _AccumuloProxy_defaultNamespace_result__isset;
+
+class AccumuloProxy_defaultNamespace_result {
+ public:
+
+  AccumuloProxy_defaultNamespace_result(const AccumuloProxy_defaultNamespace_result&);
+  AccumuloProxy_defaultNamespace_result& operator=(const AccumuloProxy_defaultNamespace_result&);
+  AccumuloProxy_defaultNamespace_result() : success() {
+  }
+
+  virtual ~AccumuloProxy_defaultNamespace_result() throw();
+  std::string success;
+
+  _AccumuloProxy_defaultNamespace_result__isset __isset;
+
+  void __set_success(const std::string& val);
+
+  bool operator == (const AccumuloProxy_defaultNamespace_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_defaultNamespace_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_defaultNamespace_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_defaultNamespace_presult__isset {
+  _AccumuloProxy_defaultNamespace_presult__isset() : success(false) {}
+  bool success :1;
+} _AccumuloProxy_defaultNamespace_presult__isset;
+
+class AccumuloProxy_defaultNamespace_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_defaultNamespace_presult() throw();
+  std::string* success;
+
+  _AccumuloProxy_defaultNamespace_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_listNamespaces_args__isset {
+  _AccumuloProxy_listNamespaces_args__isset() : login(false) {}
+  bool login :1;
+} _AccumuloProxy_listNamespaces_args__isset;
+
+class AccumuloProxy_listNamespaces_args {
+ public:
+
+  AccumuloProxy_listNamespaces_args(const AccumuloProxy_listNamespaces_args&);
+  AccumuloProxy_listNamespaces_args& operator=(const AccumuloProxy_listNamespaces_args&);
+  AccumuloProxy_listNamespaces_args() : login() {
+  }
+
+  virtual ~AccumuloProxy_listNamespaces_args() throw();
+  std::string login;
+
+  _AccumuloProxy_listNamespaces_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  bool operator == (const AccumuloProxy_listNamespaces_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_listNamespaces_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_listNamespaces_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_listNamespaces_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_listNamespaces_pargs() throw();
+  const std::string* login;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_listNamespaces_result__isset {
+  _AccumuloProxy_listNamespaces_result__isset() : success(false), ouch1(false), ouch2(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_listNamespaces_result__isset;
+
+class AccumuloProxy_listNamespaces_result {
+ public:
+
+  AccumuloProxy_listNamespaces_result(const AccumuloProxy_listNamespaces_result&);
+  AccumuloProxy_listNamespaces_result& operator=(const AccumuloProxy_listNamespaces_result&);
+  AccumuloProxy_listNamespaces_result() {
+  }
+
+  virtual ~AccumuloProxy_listNamespaces_result() throw();
+  std::vector<std::string>  success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_listNamespaces_result__isset __isset;
+
+  void __set_success(const std::vector<std::string> & val);
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  bool operator == (const AccumuloProxy_listNamespaces_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_listNamespaces_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_listNamespaces_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_listNamespaces_presult__isset {
+  _AccumuloProxy_listNamespaces_presult__isset() : success(false), ouch1(false), ouch2(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_listNamespaces_presult__isset;
+
+class AccumuloProxy_listNamespaces_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_listNamespaces_presult() throw();
+  std::vector<std::string> * success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_listNamespaces_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_namespaceExists_args__isset {
+  _AccumuloProxy_namespaceExists_args__isset() : login(false), namespaceName(false) {}
+  bool login :1;
+  bool namespaceName :1;
+} _AccumuloProxy_namespaceExists_args__isset;
+
+class AccumuloProxy_namespaceExists_args {
+ public:
+
+  AccumuloProxy_namespaceExists_args(const AccumuloProxy_namespaceExists_args&);
+  AccumuloProxy_namespaceExists_args& operator=(const AccumuloProxy_namespaceExists_args&);
+  AccumuloProxy_namespaceExists_args() : login(), namespaceName() {
+  }
+
+  virtual ~AccumuloProxy_namespaceExists_args() throw();
+  std::string login;
+  std::string namespaceName;
+
+  _AccumuloProxy_namespaceExists_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  bool operator == (const AccumuloProxy_namespaceExists_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_namespaceExists_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_namespaceExists_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_namespaceExists_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_namespaceExists_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_namespaceExists_result__isset {
+  _AccumuloProxy_namespaceExists_result__isset() : success(false), ouch1(false), ouch2(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_namespaceExists_result__isset;
+
+class AccumuloProxy_namespaceExists_result {
+ public:
+
+  AccumuloProxy_namespaceExists_result(const AccumuloProxy_namespaceExists_result&);
+  AccumuloProxy_namespaceExists_result& operator=(const AccumuloProxy_namespaceExists_result&);
+  AccumuloProxy_namespaceExists_result() : success(0) {
+  }
+
+  virtual ~AccumuloProxy_namespaceExists_result() throw();
+  bool success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_namespaceExists_result__isset __isset;
+
+  void __set_success(const bool val);
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  bool operator == (const AccumuloProxy_namespaceExists_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_namespaceExists_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_namespaceExists_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_namespaceExists_presult__isset {
+  _AccumuloProxy_namespaceExists_presult__isset() : success(false), ouch1(false), ouch2(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_namespaceExists_presult__isset;
+
+class AccumuloProxy_namespaceExists_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_namespaceExists_presult() throw();
+  bool* success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_namespaceExists_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_createNamespace_args__isset {
+  _AccumuloProxy_createNamespace_args__isset() : login(false), namespaceName(false) {}
+  bool login :1;
+  bool namespaceName :1;
+} _AccumuloProxy_createNamespace_args__isset;
+
+class AccumuloProxy_createNamespace_args {
+ public:
+
+  AccumuloProxy_createNamespace_args(const AccumuloProxy_createNamespace_args&);
+  AccumuloProxy_createNamespace_args& operator=(const AccumuloProxy_createNamespace_args&);
+  AccumuloProxy_createNamespace_args() : login(), namespaceName() {
+  }
+
+  virtual ~AccumuloProxy_createNamespace_args() throw();
+  std::string login;
+  std::string namespaceName;
+
+  _AccumuloProxy_createNamespace_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  bool operator == (const AccumuloProxy_createNamespace_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_createNamespace_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_createNamespace_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_createNamespace_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_createNamespace_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_createNamespace_result__isset {
+  _AccumuloProxy_createNamespace_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_createNamespace_result__isset;
+
+class AccumuloProxy_createNamespace_result {
+ public:
+
+  AccumuloProxy_createNamespace_result(const AccumuloProxy_createNamespace_result&);
+  AccumuloProxy_createNamespace_result& operator=(const AccumuloProxy_createNamespace_result&);
+  AccumuloProxy_createNamespace_result() {
+  }
+
+  virtual ~AccumuloProxy_createNamespace_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceExistsException ouch3;
+
+  _AccumuloProxy_createNamespace_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceExistsException& val);
+
+  bool operator == (const AccumuloProxy_createNamespace_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_createNamespace_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_createNamespace_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_createNamespace_presult__isset {
+  _AccumuloProxy_createNamespace_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_createNamespace_presult__isset;
+
+class AccumuloProxy_createNamespace_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_createNamespace_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceExistsException ouch3;
+
+  _AccumuloProxy_createNamespace_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_deleteNamespace_args__isset {
+  _AccumuloProxy_deleteNamespace_args__isset() : login(false), namespaceName(false) {}
+  bool login :1;
+  bool namespaceName :1;
+} _AccumuloProxy_deleteNamespace_args__isset;
+
+class AccumuloProxy_deleteNamespace_args {
+ public:
+
+  AccumuloProxy_deleteNamespace_args(const AccumuloProxy_deleteNamespace_args&);
+  AccumuloProxy_deleteNamespace_args& operator=(const AccumuloProxy_deleteNamespace_args&);
+  AccumuloProxy_deleteNamespace_args() : login(), namespaceName() {
+  }
+
+  virtual ~AccumuloProxy_deleteNamespace_args() throw();
+  std::string login;
+  std::string namespaceName;
+
+  _AccumuloProxy_deleteNamespace_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  bool operator == (const AccumuloProxy_deleteNamespace_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_deleteNamespace_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_deleteNamespace_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_deleteNamespace_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_deleteNamespace_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_deleteNamespace_result__isset {
+  _AccumuloProxy_deleteNamespace_result__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
+} _AccumuloProxy_deleteNamespace_result__isset;
+
+class AccumuloProxy_deleteNamespace_result {
+ public:
+
+  AccumuloProxy_deleteNamespace_result(const AccumuloProxy_deleteNamespace_result&);
+  AccumuloProxy_deleteNamespace_result& operator=(const AccumuloProxy_deleteNamespace_result&);
+  AccumuloProxy_deleteNamespace_result() {
+  }
+
+  virtual ~AccumuloProxy_deleteNamespace_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+  NamespaceNotEmptyException ouch4;
+
+  _AccumuloProxy_deleteNamespace_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  void __set_ouch4(const NamespaceNotEmptyException& val);
+
+  bool operator == (const AccumuloProxy_deleteNamespace_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    if (!(ouch4 == rhs.ouch4))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_deleteNamespace_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_deleteNamespace_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_deleteNamespace_presult__isset {
+  _AccumuloProxy_deleteNamespace_presult__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
+} _AccumuloProxy_deleteNamespace_presult__isset;
+
+class AccumuloProxy_deleteNamespace_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_deleteNamespace_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+  NamespaceNotEmptyException ouch4;
+
+  _AccumuloProxy_deleteNamespace_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_renameNamespace_args__isset {
+  _AccumuloProxy_renameNamespace_args__isset() : login(false), oldNamespaceName(false), newNamespaceName(false) {}
+  bool login :1;
+  bool oldNamespaceName :1;
+  bool newNamespaceName :1;
+} _AccumuloProxy_renameNamespace_args__isset;
+
+class AccumuloProxy_renameNamespace_args {
+ public:
+
+  AccumuloProxy_renameNamespace_args(const AccumuloProxy_renameNamespace_args&);
+  AccumuloProxy_renameNamespace_args& operator=(const AccumuloProxy_renameNamespace_args&);
+  AccumuloProxy_renameNamespace_args() : login(), oldNamespaceName(), newNamespaceName() {
+  }
+
+  virtual ~AccumuloProxy_renameNamespace_args() throw();
+  std::string login;
+  std::string oldNamespaceName;
+  std::string newNamespaceName;
+
+  _AccumuloProxy_renameNamespace_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_oldNamespaceName(const std::string& val);
+
+  void __set_newNamespaceName(const std::string& val);
+
+  bool operator == (const AccumuloProxy_renameNamespace_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(oldNamespaceName == rhs.oldNamespaceName))
+      return false;
+    if (!(newNamespaceName == rhs.newNamespaceName))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_renameNamespace_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_renameNamespace_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_renameNamespace_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_renameNamespace_pargs() throw();
+  const std::string* login;
+  const std::string* oldNamespaceName;
+  const std::string* newNamespaceName;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_renameNamespace_result__isset {
+  _AccumuloProxy_renameNamespace_result__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
+} _AccumuloProxy_renameNamespace_result__isset;
+
+class AccumuloProxy_renameNamespace_result {
+ public:
+
+  AccumuloProxy_renameNamespace_result(const AccumuloProxy_renameNamespace_result&);
+  AccumuloProxy_renameNamespace_result& operator=(const AccumuloProxy_renameNamespace_result&);
+  AccumuloProxy_renameNamespace_result() {
+  }
+
+  virtual ~AccumuloProxy_renameNamespace_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+  NamespaceExistsException ouch4;
+
+  _AccumuloProxy_renameNamespace_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  void __set_ouch4(const NamespaceExistsException& val);
+
+  bool operator == (const AccumuloProxy_renameNamespace_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    if (!(ouch4 == rhs.ouch4))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_renameNamespace_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_renameNamespace_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_renameNamespace_presult__isset {
+  _AccumuloProxy_renameNamespace_presult__isset() : ouch1(false), ouch2(false), ouch3(false), ouch4(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+  bool ouch4 :1;
+} _AccumuloProxy_renameNamespace_presult__isset;
+
+class AccumuloProxy_renameNamespace_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_renameNamespace_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+  NamespaceExistsException ouch4;
+
+  _AccumuloProxy_renameNamespace_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_setNamespaceProperty_args__isset {
+  _AccumuloProxy_setNamespaceProperty_args__isset() : login(false), namespaceName(false), property(false), value(false) {}
+  bool login :1;
+  bool namespaceName :1;
+  bool property :1;
+  bool value :1;
+} _AccumuloProxy_setNamespaceProperty_args__isset;
+
+class AccumuloProxy_setNamespaceProperty_args {
+ public:
+
+  AccumuloProxy_setNamespaceProperty_args(const AccumuloProxy_setNamespaceProperty_args&);
+  AccumuloProxy_setNamespaceProperty_args& operator=(const AccumuloProxy_setNamespaceProperty_args&);
+  AccumuloProxy_setNamespaceProperty_args() : login(), namespaceName(), property(), value() {
+  }
+
+  virtual ~AccumuloProxy_setNamespaceProperty_args() throw();
+  std::string login;
+  std::string namespaceName;
+  std::string property;
+  std::string value;
+
+  _AccumuloProxy_setNamespaceProperty_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_property(const std::string& val);
+
+  void __set_value(const std::string& val);
+
+  bool operator == (const AccumuloProxy_setNamespaceProperty_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(property == rhs.property))
+      return false;
+    if (!(value == rhs.value))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_setNamespaceProperty_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_setNamespaceProperty_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_setNamespaceProperty_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_setNamespaceProperty_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+  const std::string* property;
+  const std::string* value;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_setNamespaceProperty_result__isset {
+  _AccumuloProxy_setNamespaceProperty_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_setNamespaceProperty_result__isset;
+
+class AccumuloProxy_setNamespaceProperty_result {
+ public:
+
+  AccumuloProxy_setNamespaceProperty_result(const AccumuloProxy_setNamespaceProperty_result&);
+  AccumuloProxy_setNamespaceProperty_result& operator=(const AccumuloProxy_setNamespaceProperty_result&);
+  AccumuloProxy_setNamespaceProperty_result() {
+  }
+
+  virtual ~AccumuloProxy_setNamespaceProperty_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_setNamespaceProperty_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_setNamespaceProperty_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_setNamespaceProperty_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_setNamespaceProperty_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_setNamespaceProperty_presult__isset {
+  _AccumuloProxy_setNamespaceProperty_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_setNamespaceProperty_presult__isset;
+
+class AccumuloProxy_setNamespaceProperty_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_setNamespaceProperty_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_setNamespaceProperty_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_removeNamespaceProperty_args__isset {
+  _AccumuloProxy_removeNamespaceProperty_args__isset() : login(false), namespaceName(false), property(false) {}
+  bool login :1;
+  bool namespaceName :1;
+  bool property :1;
+} _AccumuloProxy_removeNamespaceProperty_args__isset;
+
+class AccumuloProxy_removeNamespaceProperty_args {
+ public:
+
+  AccumuloProxy_removeNamespaceProperty_args(const AccumuloProxy_removeNamespaceProperty_args&);
+  AccumuloProxy_removeNamespaceProperty_args& operator=(const AccumuloProxy_removeNamespaceProperty_args&);
+  AccumuloProxy_removeNamespaceProperty_args() : login(), namespaceName(), property() {
+  }
+
+  virtual ~AccumuloProxy_removeNamespaceProperty_args() throw();
+  std::string login;
+  std::string namespaceName;
+  std::string property;
+
+  _AccumuloProxy_removeNamespaceProperty_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_property(const std::string& val);
+
+  bool operator == (const AccumuloProxy_removeNamespaceProperty_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(property == rhs.property))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_removeNamespaceProperty_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_removeNamespaceProperty_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_removeNamespaceProperty_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_removeNamespaceProperty_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+  const std::string* property;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_removeNamespaceProperty_result__isset {
+  _AccumuloProxy_removeNamespaceProperty_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_removeNamespaceProperty_result__isset;
+
+class AccumuloProxy_removeNamespaceProperty_result {
+ public:
+
+  AccumuloProxy_removeNamespaceProperty_result(const AccumuloProxy_removeNamespaceProperty_result&);
+  AccumuloProxy_removeNamespaceProperty_result& operator=(const AccumuloProxy_removeNamespaceProperty_result&);
+  AccumuloProxy_removeNamespaceProperty_result() {
+  }
+
+  virtual ~AccumuloProxy_removeNamespaceProperty_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_removeNamespaceProperty_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_removeNamespaceProperty_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_removeNamespaceProperty_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_removeNamespaceProperty_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_removeNamespaceProperty_presult__isset {
+  _AccumuloProxy_removeNamespaceProperty_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_removeNamespaceProperty_presult__isset;
+
+class AccumuloProxy_removeNamespaceProperty_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_removeNamespaceProperty_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_removeNamespaceProperty_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_getNamespaceProperties_args__isset {
+  _AccumuloProxy_getNamespaceProperties_args__isset() : login(false), namespaceName(false) {}
+  bool login :1;
+  bool namespaceName :1;
+} _AccumuloProxy_getNamespaceProperties_args__isset;
+
+class AccumuloProxy_getNamespaceProperties_args {
+ public:
+
+  AccumuloProxy_getNamespaceProperties_args(const AccumuloProxy_getNamespaceProperties_args&);
+  AccumuloProxy_getNamespaceProperties_args& operator=(const AccumuloProxy_getNamespaceProperties_args&);
+  AccumuloProxy_getNamespaceProperties_args() : login(), namespaceName() {
+  }
+
+  virtual ~AccumuloProxy_getNamespaceProperties_args() throw();
+  std::string login;
+  std::string namespaceName;
+
+  _AccumuloProxy_getNamespaceProperties_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  bool operator == (const AccumuloProxy_getNamespaceProperties_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_getNamespaceProperties_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_getNamespaceProperties_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_getNamespaceProperties_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_getNamespaceProperties_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_getNamespaceProperties_result__isset {
+  _AccumuloProxy_getNamespaceProperties_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_getNamespaceProperties_result__isset;
+
+class AccumuloProxy_getNamespaceProperties_result {
+ public:
+
+  AccumuloProxy_getNamespaceProperties_result(const AccumuloProxy_getNamespaceProperties_result&);
+  AccumuloProxy_getNamespaceProperties_result& operator=(const AccumuloProxy_getNamespaceProperties_result&);
+  AccumuloProxy_getNamespaceProperties_result() {
+  }
+
+  virtual ~AccumuloProxy_getNamespaceProperties_result() throw();
+  std::map<std::string, std::string>  success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_getNamespaceProperties_result__isset __isset;
+
+  void __set_success(const std::map<std::string, std::string> & val);
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_getNamespaceProperties_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_getNamespaceProperties_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_getNamespaceProperties_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_getNamespaceProperties_presult__isset {
+  _AccumuloProxy_getNamespaceProperties_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_getNamespaceProperties_presult__isset;
+
+class AccumuloProxy_getNamespaceProperties_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_getNamespaceProperties_presult() throw();
+  std::map<std::string, std::string> * success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_getNamespaceProperties_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_namespaceIdMap_args__isset {
+  _AccumuloProxy_namespaceIdMap_args__isset() : login(false) {}
+  bool login :1;
+} _AccumuloProxy_namespaceIdMap_args__isset;
+
+class AccumuloProxy_namespaceIdMap_args {
+ public:
+
+  AccumuloProxy_namespaceIdMap_args(const AccumuloProxy_namespaceIdMap_args&);
+  AccumuloProxy_namespaceIdMap_args& operator=(const AccumuloProxy_namespaceIdMap_args&);
+  AccumuloProxy_namespaceIdMap_args() : login() {
+  }
+
+  virtual ~AccumuloProxy_namespaceIdMap_args() throw();
+  std::string login;
+
+  _AccumuloProxy_namespaceIdMap_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  bool operator == (const AccumuloProxy_namespaceIdMap_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_namespaceIdMap_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_namespaceIdMap_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_namespaceIdMap_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_namespaceIdMap_pargs() throw();
+  const std::string* login;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_namespaceIdMap_result__isset {
+  _AccumuloProxy_namespaceIdMap_result__isset() : success(false), ouch1(false), ouch2(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_namespaceIdMap_result__isset;
+
+class AccumuloProxy_namespaceIdMap_result {
+ public:
+
+  AccumuloProxy_namespaceIdMap_result(const AccumuloProxy_namespaceIdMap_result&);
+  AccumuloProxy_namespaceIdMap_result& operator=(const AccumuloProxy_namespaceIdMap_result&);
+  AccumuloProxy_namespaceIdMap_result() {
+  }
+
+  virtual ~AccumuloProxy_namespaceIdMap_result() throw();
+  std::map<std::string, std::string>  success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_namespaceIdMap_result__isset __isset;
+
+  void __set_success(const std::map<std::string, std::string> & val);
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  bool operator == (const AccumuloProxy_namespaceIdMap_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_namespaceIdMap_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_namespaceIdMap_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_namespaceIdMap_presult__isset {
+  _AccumuloProxy_namespaceIdMap_presult__isset() : success(false), ouch1(false), ouch2(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+} _AccumuloProxy_namespaceIdMap_presult__isset;
+
+class AccumuloProxy_namespaceIdMap_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_namespaceIdMap_presult() throw();
+  std::map<std::string, std::string> * success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+
+  _AccumuloProxy_namespaceIdMap_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_attachNamespaceIterator_args__isset {
+  _AccumuloProxy_attachNamespaceIterator_args__isset() : login(false), namespaceName(false), setting(false), scopes(false) {}
+  bool login :1;
+  bool namespaceName :1;
+  bool setting :1;
+  bool scopes :1;
+} _AccumuloProxy_attachNamespaceIterator_args__isset;
+
+class AccumuloProxy_attachNamespaceIterator_args {
+ public:
+
+  AccumuloProxy_attachNamespaceIterator_args(const AccumuloProxy_attachNamespaceIterator_args&);
+  AccumuloProxy_attachNamespaceIterator_args& operator=(const AccumuloProxy_attachNamespaceIterator_args&);
+  AccumuloProxy_attachNamespaceIterator_args() : login(), namespaceName() {
+  }
+
+  virtual ~AccumuloProxy_attachNamespaceIterator_args() throw();
+  std::string login;
+  std::string namespaceName;
+  IteratorSetting setting;
+  std::set<IteratorScope::type>  scopes;
+
+  _AccumuloProxy_attachNamespaceIterator_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_setting(const IteratorSetting& val);
+
+  void __set_scopes(const std::set<IteratorScope::type> & val);
+
+  bool operator == (const AccumuloProxy_attachNamespaceIterator_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(setting == rhs.setting))
+      return false;
+    if (!(scopes == rhs.scopes))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_attachNamespaceIterator_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_attachNamespaceIterator_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_attachNamespaceIterator_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_attachNamespaceIterator_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+  const IteratorSetting* setting;
+  const std::set<IteratorScope::type> * scopes;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_attachNamespaceIterator_result__isset {
+  _AccumuloProxy_attachNamespaceIterator_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_attachNamespaceIterator_result__isset;
+
+class AccumuloProxy_attachNamespaceIterator_result {
+ public:
+
+  AccumuloProxy_attachNamespaceIterator_result(const AccumuloProxy_attachNamespaceIterator_result&);
+  AccumuloProxy_attachNamespaceIterator_result& operator=(const AccumuloProxy_attachNamespaceIterator_result&);
+  AccumuloProxy_attachNamespaceIterator_result() {
+  }
+
+  virtual ~AccumuloProxy_attachNamespaceIterator_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_attachNamespaceIterator_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_attachNamespaceIterator_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_attachNamespaceIterator_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_attachNamespaceIterator_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_attachNamespaceIterator_presult__isset {
+  _AccumuloProxy_attachNamespaceIterator_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_attachNamespaceIterator_presult__isset;
+
+class AccumuloProxy_attachNamespaceIterator_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_attachNamespaceIterator_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_attachNamespaceIterator_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_removeNamespaceIterator_args__isset {
+  _AccumuloProxy_removeNamespaceIterator_args__isset() : login(false), namespaceName(false), name(false), scopes(false) {}
+  bool login :1;
+  bool namespaceName :1;
+  bool name :1;
+  bool scopes :1;
+} _AccumuloProxy_removeNamespaceIterator_args__isset;
+
+class AccumuloProxy_removeNamespaceIterator_args {
+ public:
+
+  AccumuloProxy_removeNamespaceIterator_args(const AccumuloProxy_removeNamespaceIterator_args&);
+  AccumuloProxy_removeNamespaceIterator_args& operator=(const AccumuloProxy_removeNamespaceIterator_args&);
+  AccumuloProxy_removeNamespaceIterator_args() : login(), namespaceName(), name() {
+  }
+
+  virtual ~AccumuloProxy_removeNamespaceIterator_args() throw();
+  std::string login;
+  std::string namespaceName;
+  std::string name;
+  std::set<IteratorScope::type>  scopes;
+
+  _AccumuloProxy_removeNamespaceIterator_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_name(const std::string& val);
+
+  void __set_scopes(const std::set<IteratorScope::type> & val);
+
+  bool operator == (const AccumuloProxy_removeNamespaceIterator_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(name == rhs.name))
+      return false;
+    if (!(scopes == rhs.scopes))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_removeNamespaceIterator_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_removeNamespaceIterator_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_removeNamespaceIterator_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_removeNamespaceIterator_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+  const std::string* name;
+  const std::set<IteratorScope::type> * scopes;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_removeNamespaceIterator_result__isset {
+  _AccumuloProxy_removeNamespaceIterator_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_removeNamespaceIterator_result__isset;
+
+class AccumuloProxy_removeNamespaceIterator_result {
+ public:
+
+  AccumuloProxy_removeNamespaceIterator_result(const AccumuloProxy_removeNamespaceIterator_result&);
+  AccumuloProxy_removeNamespaceIterator_result& operator=(const AccumuloProxy_removeNamespaceIterator_result&);
+  AccumuloProxy_removeNamespaceIterator_result() {
+  }
+
+  virtual ~AccumuloProxy_removeNamespaceIterator_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_removeNamespaceIterator_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_removeNamespaceIterator_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_removeNamespaceIterator_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_removeNamespaceIterator_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_removeNamespaceIterator_presult__isset {
+  _AccumuloProxy_removeNamespaceIterator_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_removeNamespaceIterator_presult__isset;
+
+class AccumuloProxy_removeNamespaceIterator_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_removeNamespaceIterator_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_removeNamespaceIterator_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_getNamespaceIteratorSetting_args__isset {
+  _AccumuloProxy_getNamespaceIteratorSetting_args__isset() : login(false), namespaceName(false), name(false), scope(false) {}
+  bool login :1;
+  bool namespaceName :1;
+  bool name :1;
+  bool scope :1;
+} _AccumuloProxy_getNamespaceIteratorSetting_args__isset;
+
+class AccumuloProxy_getNamespaceIteratorSetting_args {
+ public:
+
+  AccumuloProxy_getNamespaceIteratorSetting_args(const AccumuloProxy_getNamespaceIteratorSetting_args&);
+  AccumuloProxy_getNamespaceIteratorSetting_args& operator=(const AccumuloProxy_getNamespaceIteratorSetting_args&);
+  AccumuloProxy_getNamespaceIteratorSetting_args() : login(), namespaceName(), name(), scope((IteratorScope::type)0) {
+  }
+
+  virtual ~AccumuloProxy_getNamespaceIteratorSetting_args() throw();
+  std::string login;
+  std::string namespaceName;
+  std::string name;
+  IteratorScope::type scope;
+
+  _AccumuloProxy_getNamespaceIteratorSetting_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_name(const std::string& val);
+
+  void __set_scope(const IteratorScope::type val);
+
+  bool operator == (const AccumuloProxy_getNamespaceIteratorSetting_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(name == rhs.name))
+      return false;
+    if (!(scope == rhs.scope))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_getNamespaceIteratorSetting_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_getNamespaceIteratorSetting_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_getNamespaceIteratorSetting_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_getNamespaceIteratorSetting_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+  const std::string* name;
+  const IteratorScope::type* scope;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_getNamespaceIteratorSetting_result__isset {
+  _AccumuloProxy_getNamespaceIteratorSetting_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_getNamespaceIteratorSetting_result__isset;
+
+class AccumuloProxy_getNamespaceIteratorSetting_result {
+ public:
+
+  AccumuloProxy_getNamespaceIteratorSetting_result(const AccumuloProxy_getNamespaceIteratorSetting_result&);
+  AccumuloProxy_getNamespaceIteratorSetting_result& operator=(const AccumuloProxy_getNamespaceIteratorSetting_result&);
+  AccumuloProxy_getNamespaceIteratorSetting_result() {
+  }
+
+  virtual ~AccumuloProxy_getNamespaceIteratorSetting_result() throw();
+  IteratorSetting success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_getNamespaceIteratorSetting_result__isset __isset;
+
+  void __set_success(const IteratorSetting& val);
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_getNamespaceIteratorSetting_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_getNamespaceIteratorSetting_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_getNamespaceIteratorSetting_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_getNamespaceIteratorSetting_presult__isset {
+  _AccumuloProxy_getNamespaceIteratorSetting_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_getNamespaceIteratorSetting_presult__isset;
+
+class AccumuloProxy_getNamespaceIteratorSetting_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_getNamespaceIteratorSetting_presult() throw();
+  IteratorSetting* success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_getNamespaceIteratorSetting_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_listNamespaceIterators_args__isset {
+  _AccumuloProxy_listNamespaceIterators_args__isset() : login(false), namespaceName(false) {}
+  bool login :1;
+  bool namespaceName :1;
+} _AccumuloProxy_listNamespaceIterators_args__isset;
+
+class AccumuloProxy_listNamespaceIterators_args {
+ public:
+
+  AccumuloProxy_listNamespaceIterators_args(const AccumuloProxy_listNamespaceIterators_args&);
+  AccumuloProxy_listNamespaceIterators_args& operator=(const AccumuloProxy_listNamespaceIterators_args&);
+  AccumuloProxy_listNamespaceIterators_args() : login(), namespaceName() {
+  }
+
+  virtual ~AccumuloProxy_listNamespaceIterators_args() throw();
+  std::string login;
+  std::string namespaceName;
+
+  _AccumuloProxy_listNamespaceIterators_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  bool operator == (const AccumuloProxy_listNamespaceIterators_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_listNamespaceIterators_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_listNamespaceIterators_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_listNamespaceIterators_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_listNamespaceIterators_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_listNamespaceIterators_result__isset {
+  _AccumuloProxy_listNamespaceIterators_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_listNamespaceIterators_result__isset;
+
+class AccumuloProxy_listNamespaceIterators_result {
+ public:
+
+  AccumuloProxy_listNamespaceIterators_result(const AccumuloProxy_listNamespaceIterators_result&);
+  AccumuloProxy_listNamespaceIterators_result& operator=(const AccumuloProxy_listNamespaceIterators_result&);
+  AccumuloProxy_listNamespaceIterators_result() {
+  }
+
+  virtual ~AccumuloProxy_listNamespaceIterators_result() throw();
+  std::map<std::string, std::set<IteratorScope::type> >  success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_listNamespaceIterators_result__isset __isset;
+
+  void __set_success(const std::map<std::string, std::set<IteratorScope::type> > & val);
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_listNamespaceIterators_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_listNamespaceIterators_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_listNamespaceIterators_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_listNamespaceIterators_presult__isset {
+  _AccumuloProxy_listNamespaceIterators_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_listNamespaceIterators_presult__isset;
+
+class AccumuloProxy_listNamespaceIterators_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_listNamespaceIterators_presult() throw();
+  std::map<std::string, std::set<IteratorScope::type> > * success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_listNamespaceIterators_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_checkNamespaceIteratorConflicts_args__isset {
+  _AccumuloProxy_checkNamespaceIteratorConflicts_args__isset() : login(false), namespaceName(false), setting(false), scopes(false) {}
+  bool login :1;
+  bool namespaceName :1;
+  bool setting :1;
+  bool scopes :1;
+} _AccumuloProxy_checkNamespaceIteratorConflicts_args__isset;
+
+class AccumuloProxy_checkNamespaceIteratorConflicts_args {
+ public:
+
+  AccumuloProxy_checkNamespaceIteratorConflicts_args(const AccumuloProxy_checkNamespaceIteratorConflicts_args&);
+  AccumuloProxy_checkNamespaceIteratorConflicts_args& operator=(const AccumuloProxy_checkNamespaceIteratorConflicts_args&);
+  AccumuloProxy_checkNamespaceIteratorConflicts_args() : login(), namespaceName() {
+  }
+
+  virtual ~AccumuloProxy_checkNamespaceIteratorConflicts_args() throw();
+  std::string login;
+  std::string namespaceName;
+  IteratorSetting setting;
+  std::set<IteratorScope::type>  scopes;
+
+  _AccumuloProxy_checkNamespaceIteratorConflicts_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_setting(const IteratorSetting& val);
+
+  void __set_scopes(const std::set<IteratorScope::type> & val);
+
+  bool operator == (const AccumuloProxy_checkNamespaceIteratorConflicts_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(setting == rhs.setting))
+      return false;
+    if (!(scopes == rhs.scopes))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_checkNamespaceIteratorConflicts_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_checkNamespaceIteratorConflicts_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_checkNamespaceIteratorConflicts_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_checkNamespaceIteratorConflicts_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+  const IteratorSetting* setting;
+  const std::set<IteratorScope::type> * scopes;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_checkNamespaceIteratorConflicts_result__isset {
+  _AccumuloProxy_checkNamespaceIteratorConflicts_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_checkNamespaceIteratorConflicts_result__isset;
+
+class AccumuloProxy_checkNamespaceIteratorConflicts_result {
+ public:
+
+  AccumuloProxy_checkNamespaceIteratorConflicts_result(const AccumuloProxy_checkNamespaceIteratorConflicts_result&);
+  AccumuloProxy_checkNamespaceIteratorConflicts_result& operator=(const AccumuloProxy_checkNamespaceIteratorConflicts_result&);
+  AccumuloProxy_checkNamespaceIteratorConflicts_result() {
+  }
+
+  virtual ~AccumuloProxy_checkNamespaceIteratorConflicts_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_checkNamespaceIteratorConflicts_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_checkNamespaceIteratorConflicts_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_checkNamespaceIteratorConflicts_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_checkNamespaceIteratorConflicts_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_checkNamespaceIteratorConflicts_presult__isset {
+  _AccumuloProxy_checkNamespaceIteratorConflicts_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_checkNamespaceIteratorConflicts_presult__isset;
+
+class AccumuloProxy_checkNamespaceIteratorConflicts_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_checkNamespaceIteratorConflicts_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_checkNamespaceIteratorConflicts_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_addNamespaceConstraint_args__isset {
+  _AccumuloProxy_addNamespaceConstraint_args__isset() : login(false), namespaceName(false), constraintClassName(false) {}
+  bool login :1;
+  bool namespaceName :1;
+  bool constraintClassName :1;
+} _AccumuloProxy_addNamespaceConstraint_args__isset;
+
+class AccumuloProxy_addNamespaceConstraint_args {
+ public:
+
+  AccumuloProxy_addNamespaceConstraint_args(const AccumuloProxy_addNamespaceConstraint_args&);
+  AccumuloProxy_addNamespaceConstraint_args& operator=(const AccumuloProxy_addNamespaceConstraint_args&);
+  AccumuloProxy_addNamespaceConstraint_args() : login(), namespaceName(), constraintClassName() {
+  }
+
+  virtual ~AccumuloProxy_addNamespaceConstraint_args() throw();
+  std::string login;
+  std::string namespaceName;
+  std::string constraintClassName;
+
+  _AccumuloProxy_addNamespaceConstraint_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_constraintClassName(const std::string& val);
+
+  bool operator == (const AccumuloProxy_addNamespaceConstraint_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(constraintClassName == rhs.constraintClassName))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_addNamespaceConstraint_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_addNamespaceConstraint_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_addNamespaceConstraint_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_addNamespaceConstraint_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+  const std::string* constraintClassName;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_addNamespaceConstraint_result__isset {
+  _AccumuloProxy_addNamespaceConstraint_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_addNamespaceConstraint_result__isset;
+
+class AccumuloProxy_addNamespaceConstraint_result {
+ public:
+
+  AccumuloProxy_addNamespaceConstraint_result(const AccumuloProxy_addNamespaceConstraint_result&);
+  AccumuloProxy_addNamespaceConstraint_result& operator=(const AccumuloProxy_addNamespaceConstraint_result&);
+  AccumuloProxy_addNamespaceConstraint_result() : success(0) {
+  }
+
+  virtual ~AccumuloProxy_addNamespaceConstraint_result() throw();
+  int32_t success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_addNamespaceConstraint_result__isset __isset;
+
+  void __set_success(const int32_t val);
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_addNamespaceConstraint_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_addNamespaceConstraint_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_addNamespaceConstraint_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_addNamespaceConstraint_presult__isset {
+  _AccumuloProxy_addNamespaceConstraint_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_addNamespaceConstraint_presult__isset;
+
+class AccumuloProxy_addNamespaceConstraint_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_addNamespaceConstraint_presult() throw();
+  int32_t* success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_addNamespaceConstraint_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_removeNamespaceConstraint_args__isset {
+  _AccumuloProxy_removeNamespaceConstraint_args__isset() : login(false), namespaceName(false), id(false) {}
+  bool login :1;
+  bool namespaceName :1;
+  bool id :1;
+} _AccumuloProxy_removeNamespaceConstraint_args__isset;
+
+class AccumuloProxy_removeNamespaceConstraint_args {
+ public:
+
+  AccumuloProxy_removeNamespaceConstraint_args(const AccumuloProxy_removeNamespaceConstraint_args&);
+  AccumuloProxy_removeNamespaceConstraint_args& operator=(const AccumuloProxy_removeNamespaceConstraint_args&);
+  AccumuloProxy_removeNamespaceConstraint_args() : login(), namespaceName(), id(0) {
+  }
+
+  virtual ~AccumuloProxy_removeNamespaceConstraint_args() throw();
+  std::string login;
+  std::string namespaceName;
+  int32_t id;
+
+  _AccumuloProxy_removeNamespaceConstraint_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_id(const int32_t val);
+
+  bool operator == (const AccumuloProxy_removeNamespaceConstraint_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(id == rhs.id))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_removeNamespaceConstraint_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_removeNamespaceConstraint_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_removeNamespaceConstraint_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_removeNamespaceConstraint_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+  const int32_t* id;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_removeNamespaceConstraint_result__isset {
+  _AccumuloProxy_removeNamespaceConstraint_result__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_removeNamespaceConstraint_result__isset;
+
+class AccumuloProxy_removeNamespaceConstraint_result {
+ public:
+
+  AccumuloProxy_removeNamespaceConstraint_result(const AccumuloProxy_removeNamespaceConstraint_result&);
+  AccumuloProxy_removeNamespaceConstraint_result& operator=(const AccumuloProxy_removeNamespaceConstraint_result&);
+  AccumuloProxy_removeNamespaceConstraint_result() {
+  }
+
+  virtual ~AccumuloProxy_removeNamespaceConstraint_result() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_removeNamespaceConstraint_result__isset __isset;
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_removeNamespaceConstraint_result & rhs) const
+  {
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_removeNamespaceConstraint_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_removeNamespaceConstraint_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_removeNamespaceConstraint_presult__isset {
+  _AccumuloProxy_removeNamespaceConstraint_presult__isset() : ouch1(false), ouch2(false), ouch3(false) {}
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_removeNamespaceConstraint_presult__isset;
+
+class AccumuloProxy_removeNamespaceConstraint_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_removeNamespaceConstraint_presult() throw();
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_removeNamespaceConstraint_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_listNamespaceConstraints_args__isset {
+  _AccumuloProxy_listNamespaceConstraints_args__isset() : login(false), namespaceName(false) {}
+  bool login :1;
+  bool namespaceName :1;
+} _AccumuloProxy_listNamespaceConstraints_args__isset;
+
+class AccumuloProxy_listNamespaceConstraints_args {
+ public:
+
+  AccumuloProxy_listNamespaceConstraints_args(const AccumuloProxy_listNamespaceConstraints_args&);
+  AccumuloProxy_listNamespaceConstraints_args& operator=(const AccumuloProxy_listNamespaceConstraints_args&);
+  AccumuloProxy_listNamespaceConstraints_args() : login(), namespaceName() {
+  }
+
+  virtual ~AccumuloProxy_listNamespaceConstraints_args() throw();
+  std::string login;
+  std::string namespaceName;
+
+  _AccumuloProxy_listNamespaceConstraints_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  bool operator == (const AccumuloProxy_listNamespaceConstraints_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_listNamespaceConstraints_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_listNamespaceConstraints_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_listNamespaceConstraints_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_listNamespaceConstraints_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_listNamespaceConstraints_result__isset {
+  _AccumuloProxy_listNamespaceConstraints_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_listNamespaceConstraints_result__isset;
+
+class AccumuloProxy_listNamespaceConstraints_result {
+ public:
+
+  AccumuloProxy_listNamespaceConstraints_result(const AccumuloProxy_listNamespaceConstraints_result&);
+  AccumuloProxy_listNamespaceConstraints_result& operator=(const AccumuloProxy_listNamespaceConstraints_result&);
+  AccumuloProxy_listNamespaceConstraints_result() {
+  }
+
+  virtual ~AccumuloProxy_listNamespaceConstraints_result() throw();
+  std::map<std::string, int32_t>  success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_listNamespaceConstraints_result__isset __isset;
+
+  void __set_success(const std::map<std::string, int32_t> & val);
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_listNamespaceConstraints_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_listNamespaceConstraints_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_listNamespaceConstraints_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_listNamespaceConstraints_presult__isset {
+  _AccumuloProxy_listNamespaceConstraints_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_listNamespaceConstraints_presult__isset;
+
+class AccumuloProxy_listNamespaceConstraints_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_listNamespaceConstraints_presult() throw();
+  std::map<std::string, int32_t> * success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_listNamespaceConstraints_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
+typedef struct _AccumuloProxy_testNamespaceClassLoad_args__isset {
+  _AccumuloProxy_testNamespaceClassLoad_args__isset() : login(false), namespaceName(false), className(false), asTypeName(false) {}
+  bool login :1;
+  bool namespaceName :1;
+  bool className :1;
+  bool asTypeName :1;
+} _AccumuloProxy_testNamespaceClassLoad_args__isset;
+
+class AccumuloProxy_testNamespaceClassLoad_args {
+ public:
+
+  AccumuloProxy_testNamespaceClassLoad_args(const AccumuloProxy_testNamespaceClassLoad_args&);
+  AccumuloProxy_testNamespaceClassLoad_args& operator=(const AccumuloProxy_testNamespaceClassLoad_args&);
+  AccumuloProxy_testNamespaceClassLoad_args() : login(), namespaceName(), className(), asTypeName() {
+  }
+
+  virtual ~AccumuloProxy_testNamespaceClassLoad_args() throw();
+  std::string login;
+  std::string namespaceName;
+  std::string className;
+  std::string asTypeName;
+
+  _AccumuloProxy_testNamespaceClassLoad_args__isset __isset;
+
+  void __set_login(const std::string& val);
+
+  void __set_namespaceName(const std::string& val);
+
+  void __set_className(const std::string& val);
+
+  void __set_asTypeName(const std::string& val);
+
+  bool operator == (const AccumuloProxy_testNamespaceClassLoad_args & rhs) const
+  {
+    if (!(login == rhs.login))
+      return false;
+    if (!(namespaceName == rhs.namespaceName))
+      return false;
+    if (!(className == rhs.className))
+      return false;
+    if (!(asTypeName == rhs.asTypeName))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_testNamespaceClassLoad_args &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_testNamespaceClassLoad_args & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+
+class AccumuloProxy_testNamespaceClassLoad_pargs {
+ public:
+
+
+  virtual ~AccumuloProxy_testNamespaceClassLoad_pargs() throw();
+  const std::string* login;
+  const std::string* namespaceName;
+  const std::string* className;
+  const std::string* asTypeName;
+
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_testNamespaceClassLoad_result__isset {
+  _AccumuloProxy_testNamespaceClassLoad_result__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_testNamespaceClassLoad_result__isset;
+
+class AccumuloProxy_testNamespaceClassLoad_result {
+ public:
+
+  AccumuloProxy_testNamespaceClassLoad_result(const AccumuloProxy_testNamespaceClassLoad_result&);
+  AccumuloProxy_testNamespaceClassLoad_result& operator=(const AccumuloProxy_testNamespaceClassLoad_result&);
+  AccumuloProxy_testNamespaceClassLoad_result() : success(0) {
+  }
+
+  virtual ~AccumuloProxy_testNamespaceClassLoad_result() throw();
+  bool success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_testNamespaceClassLoad_result__isset __isset;
+
+  void __set_success(const bool val);
+
+  void __set_ouch1(const AccumuloException& val);
+
+  void __set_ouch2(const AccumuloSecurityException& val);
+
+  void __set_ouch3(const NamespaceNotFoundException& val);
+
+  bool operator == (const AccumuloProxy_testNamespaceClassLoad_result & rhs) const
+  {
+    if (!(success == rhs.success))
+      return false;
+    if (!(ouch1 == rhs.ouch1))
+      return false;
+    if (!(ouch2 == rhs.ouch2))
+      return false;
+    if (!(ouch3 == rhs.ouch3))
+      return false;
+    return true;
+  }
+  bool operator != (const AccumuloProxy_testNamespaceClassLoad_result &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const AccumuloProxy_testNamespaceClassLoad_result & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+};
+
+typedef struct _AccumuloProxy_testNamespaceClassLoad_presult__isset {
+  _AccumuloProxy_testNamespaceClassLoad_presult__isset() : success(false), ouch1(false), ouch2(false), ouch3(false) {}
+  bool success :1;
+  bool ouch1 :1;
+  bool ouch2 :1;
+  bool ouch3 :1;
+} _AccumuloProxy_testNamespaceClassLoad_presult__isset;
+
+class AccumuloProxy_testNamespaceClassLoad_presult {
+ public:
+
+
+  virtual ~AccumuloProxy_testNamespaceClassLoad_presult() throw();
+  bool* success;
+  AccumuloException ouch1;
+  AccumuloSecurityException ouch2;
+  NamespaceNotFoundException ouch3;
+
+  _AccumuloProxy_testNamespaceClassLoad_presult__isset __isset;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+
+};
+
 class AccumuloProxyClient : virtual public AccumuloProxyIf {
  public:
-  AccumuloProxyClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) :
-    piprot_(prot),
-    poprot_(prot) {
-    iprot_ = prot.get();
-    oprot_ = prot.get();
+  AccumuloProxyClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+    setProtocol(prot);
   }
-  AccumuloProxyClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) :
-    piprot_(iprot),
-    poprot_(oprot) {
+  AccumuloProxyClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+    setProtocol(iprot,oprot);
+  }
+ private:
+  void setProtocol(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+  setProtocol(prot,prot);
+  }
+  void setProtocol(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+    piprot_=iprot;
+    poprot_=oprot;
     iprot_ = iprot.get();
     oprot_ = oprot.get();
   }
+ public:
   boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
     return piprot_;
   }
@@ -11510,6 +13786,15 @@
   void revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
   void send_revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
   void recv_revokeTablePermission();
+  void grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  void send_grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  void recv_grantNamespacePermission();
+  bool hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  void send_hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  bool recv_hasNamespacePermission();
+  void revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  void send_revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  void recv_revokeNamespacePermission();
   void createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options);
   void send_createBatchScanner(const std::string& login, const std::string& tableName, const BatchScanOptions& options);
   void recv_createBatchScanner(std::string& _return);
@@ -11560,6 +13845,66 @@
   void getFollowing(Key& _return, const Key& key, const PartialKey::type part);
   void send_getFollowing(const Key& key, const PartialKey::type part);
   void recv_getFollowing(Key& _return);
+  void systemNamespace(std::string& _return);
+  void send_systemNamespace();
+  void recv_systemNamespace(std::string& _return);
+  void defaultNamespace(std::string& _return);
+  void send_defaultNamespace();
+  void recv_defaultNamespace(std::string& _return);
+  void listNamespaces(std::vector<std::string> & _return, const std::string& login);
+  void send_listNamespaces(const std::string& login);
+  void recv_listNamespaces(std::vector<std::string> & _return);
+  bool namespaceExists(const std::string& login, const std::string& namespaceName);
+  void send_namespaceExists(const std::string& login, const std::string& namespaceName);
+  bool recv_namespaceExists();
+  void createNamespace(const std::string& login, const std::string& namespaceName);
+  void send_createNamespace(const std::string& login, const std::string& namespaceName);
+  void recv_createNamespace();
+  void deleteNamespace(const std::string& login, const std::string& namespaceName);
+  void send_deleteNamespace(const std::string& login, const std::string& namespaceName);
+  void recv_deleteNamespace();
+  void renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName);
+  void send_renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName);
+  void recv_renameNamespace();
+  void setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value);
+  void send_setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value);
+  void recv_setNamespaceProperty();
+  void removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property);
+  void send_removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property);
+  void recv_removeNamespaceProperty();
+  void getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName);
+  void send_getNamespaceProperties(const std::string& login, const std::string& namespaceName);
+  void recv_getNamespaceProperties(std::map<std::string, std::string> & _return);
+  void namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login);
+  void send_namespaceIdMap(const std::string& login);
+  void recv_namespaceIdMap(std::map<std::string, std::string> & _return);
+  void attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  void send_attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  void recv_attachNamespaceIterator();
+  void removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes);
+  void send_removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes);
+  void recv_removeNamespaceIterator();
+  void getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope);
+  void send_getNamespaceIteratorSetting(const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope);
+  void recv_getNamespaceIteratorSetting(IteratorSetting& _return);
+  void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName);
+  void send_listNamespaceIterators(const std::string& login, const std::string& namespaceName);
+  void recv_listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return);
+  void checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  void send_checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  void recv_checkNamespaceIteratorConflicts();
+  int32_t addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName);
+  void send_addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName);
+  int32_t recv_addNamespaceConstraint();
+  void removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id);
+  void send_removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id);
+  void recv_removeNamespaceConstraint();
+  void listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName);
+  void send_listNamespaceConstraints(const std::string& login, const std::string& namespaceName);
+  void recv_listNamespaceConstraints(std::map<std::string, int32_t> & _return);
+  bool testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName);
+  void send_testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName);
+  bool recv_testNamespaceClassLoad();
  protected:
   boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
   boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
@@ -11635,6 +13980,9 @@
   void process_listLocalUsers(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
   void process_revokeSystemPermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
   void process_revokeTablePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_grantNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_hasNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_revokeNamespacePermission(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
   void process_createBatchScanner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
   void process_createScanner(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
   void process_hasNext(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
@@ -11652,6 +14000,26 @@
   void process_closeConditionalWriter(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
   void process_getRowRange(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
   void process_getFollowing(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_systemNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_defaultNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_listNamespaces(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_namespaceExists(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_createNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_deleteNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_renameNamespace(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_setNamespaceProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_removeNamespaceProperty(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_getNamespaceProperties(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_namespaceIdMap(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_attachNamespaceIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_removeNamespaceIterator(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_getNamespaceIteratorSetting(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_listNamespaceIterators(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_checkNamespaceIteratorConflicts(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_addNamespaceConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_removeNamespaceConstraint(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_listNamespaceConstraints(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
+  void process_testNamespaceClassLoad(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
  public:
   AccumuloProxyProcessor(boost::shared_ptr<AccumuloProxyIf> iface) :
     iface_(iface) {
@@ -11715,6 +14083,9 @@
     processMap_["listLocalUsers"] = &AccumuloProxyProcessor::process_listLocalUsers;
     processMap_["revokeSystemPermission"] = &AccumuloProxyProcessor::process_revokeSystemPermission;
     processMap_["revokeTablePermission"] = &AccumuloProxyProcessor::process_revokeTablePermission;
+    processMap_["grantNamespacePermission"] = &AccumuloProxyProcessor::process_grantNamespacePermission;
+    processMap_["hasNamespacePermission"] = &AccumuloProxyProcessor::process_hasNamespacePermission;
+    processMap_["revokeNamespacePermission"] = &AccumuloProxyProcessor::process_revokeNamespacePermission;
     processMap_["createBatchScanner"] = &AccumuloProxyProcessor::process_createBatchScanner;
     processMap_["createScanner"] = &AccumuloProxyProcessor::process_createScanner;
     processMap_["hasNext"] = &AccumuloProxyProcessor::process_hasNext;
@@ -11732,6 +14103,26 @@
     processMap_["closeConditionalWriter"] = &AccumuloProxyProcessor::process_closeConditionalWriter;
     processMap_["getRowRange"] = &AccumuloProxyProcessor::process_getRowRange;
     processMap_["getFollowing"] = &AccumuloProxyProcessor::process_getFollowing;
+    processMap_["systemNamespace"] = &AccumuloProxyProcessor::process_systemNamespace;
+    processMap_["defaultNamespace"] = &AccumuloProxyProcessor::process_defaultNamespace;
+    processMap_["listNamespaces"] = &AccumuloProxyProcessor::process_listNamespaces;
+    processMap_["namespaceExists"] = &AccumuloProxyProcessor::process_namespaceExists;
+    processMap_["createNamespace"] = &AccumuloProxyProcessor::process_createNamespace;
+    processMap_["deleteNamespace"] = &AccumuloProxyProcessor::process_deleteNamespace;
+    processMap_["renameNamespace"] = &AccumuloProxyProcessor::process_renameNamespace;
+    processMap_["setNamespaceProperty"] = &AccumuloProxyProcessor::process_setNamespaceProperty;
+    processMap_["removeNamespaceProperty"] = &AccumuloProxyProcessor::process_removeNamespaceProperty;
+    processMap_["getNamespaceProperties"] = &AccumuloProxyProcessor::process_getNamespaceProperties;
+    processMap_["namespaceIdMap"] = &AccumuloProxyProcessor::process_namespaceIdMap;
+    processMap_["attachNamespaceIterator"] = &AccumuloProxyProcessor::process_attachNamespaceIterator;
+    processMap_["removeNamespaceIterator"] = &AccumuloProxyProcessor::process_removeNamespaceIterator;
+    processMap_["getNamespaceIteratorSetting"] = &AccumuloProxyProcessor::process_getNamespaceIteratorSetting;
+    processMap_["listNamespaceIterators"] = &AccumuloProxyProcessor::process_listNamespaceIterators;
+    processMap_["checkNamespaceIteratorConflicts"] = &AccumuloProxyProcessor::process_checkNamespaceIteratorConflicts;
+    processMap_["addNamespaceConstraint"] = &AccumuloProxyProcessor::process_addNamespaceConstraint;
+    processMap_["removeNamespaceConstraint"] = &AccumuloProxyProcessor::process_removeNamespaceConstraint;
+    processMap_["listNamespaceConstraints"] = &AccumuloProxyProcessor::process_listNamespaceConstraints;
+    processMap_["testNamespaceClassLoad"] = &AccumuloProxyProcessor::process_testNamespaceClassLoad;
   }
 
   virtual ~AccumuloProxyProcessor() {}
@@ -12319,6 +14710,33 @@
     ifaces_[i]->revokeTablePermission(login, user, table, perm);
   }
 
+  void grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->grantNamespacePermission(login, user, namespaceName, perm);
+    }
+    ifaces_[i]->grantNamespacePermission(login, user, namespaceName, perm);
+  }
+
+  bool hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->hasNamespacePermission(login, user, namespaceName, perm);
+    }
+    return ifaces_[i]->hasNamespacePermission(login, user, namespaceName, perm);
+  }
+
+  void revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->revokeNamespacePermission(login, user, namespaceName, perm);
+    }
+    ifaces_[i]->revokeNamespacePermission(login, user, namespaceName, perm);
+  }
+
   void createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options) {
     size_t sz = ifaces_.size();
     size_t i = 0;
@@ -12481,8 +14899,535 @@
     return;
   }
 
+  void systemNamespace(std::string& _return) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->systemNamespace(_return);
+    }
+    ifaces_[i]->systemNamespace(_return);
+    return;
+  }
+
+  void defaultNamespace(std::string& _return) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->defaultNamespace(_return);
+    }
+    ifaces_[i]->defaultNamespace(_return);
+    return;
+  }
+
+  void listNamespaces(std::vector<std::string> & _return, const std::string& login) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->listNamespaces(_return, login);
+    }
+    ifaces_[i]->listNamespaces(_return, login);
+    return;
+  }
+
+  bool namespaceExists(const std::string& login, const std::string& namespaceName) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->namespaceExists(login, namespaceName);
+    }
+    return ifaces_[i]->namespaceExists(login, namespaceName);
+  }
+
+  void createNamespace(const std::string& login, const std::string& namespaceName) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->createNamespace(login, namespaceName);
+    }
+    ifaces_[i]->createNamespace(login, namespaceName);
+  }
+
+  void deleteNamespace(const std::string& login, const std::string& namespaceName) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->deleteNamespace(login, namespaceName);
+    }
+    ifaces_[i]->deleteNamespace(login, namespaceName);
+  }
+
+  void renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->renameNamespace(login, oldNamespaceName, newNamespaceName);
+    }
+    ifaces_[i]->renameNamespace(login, oldNamespaceName, newNamespaceName);
+  }
+
+  void setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->setNamespaceProperty(login, namespaceName, property, value);
+    }
+    ifaces_[i]->setNamespaceProperty(login, namespaceName, property, value);
+  }
+
+  void removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->removeNamespaceProperty(login, namespaceName, property);
+    }
+    ifaces_[i]->removeNamespaceProperty(login, namespaceName, property);
+  }
+
+  void getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->getNamespaceProperties(_return, login, namespaceName);
+    }
+    ifaces_[i]->getNamespaceProperties(_return, login, namespaceName);
+    return;
+  }
+
+  void namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->namespaceIdMap(_return, login);
+    }
+    ifaces_[i]->namespaceIdMap(_return, login);
+    return;
+  }
+
+  void attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->attachNamespaceIterator(login, namespaceName, setting, scopes);
+    }
+    ifaces_[i]->attachNamespaceIterator(login, namespaceName, setting, scopes);
+  }
+
+  void removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->removeNamespaceIterator(login, namespaceName, name, scopes);
+    }
+    ifaces_[i]->removeNamespaceIterator(login, namespaceName, name, scopes);
+  }
+
+  void getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->getNamespaceIteratorSetting(_return, login, namespaceName, name, scope);
+    }
+    ifaces_[i]->getNamespaceIteratorSetting(_return, login, namespaceName, name, scope);
+    return;
+  }
+
+  void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->listNamespaceIterators(_return, login, namespaceName);
+    }
+    ifaces_[i]->listNamespaceIterators(_return, login, namespaceName);
+    return;
+  }
+
+  void checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes);
+    }
+    ifaces_[i]->checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes);
+  }
+
+  int32_t addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->addNamespaceConstraint(login, namespaceName, constraintClassName);
+    }
+    return ifaces_[i]->addNamespaceConstraint(login, namespaceName, constraintClassName);
+  }
+
+  void removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->removeNamespaceConstraint(login, namespaceName, id);
+    }
+    ifaces_[i]->removeNamespaceConstraint(login, namespaceName, id);
+  }
+
+  void listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->listNamespaceConstraints(_return, login, namespaceName);
+    }
+    ifaces_[i]->listNamespaceConstraints(_return, login, namespaceName);
+    return;
+  }
+
+  bool testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName) {
+    size_t sz = ifaces_.size();
+    size_t i = 0;
+    for (; i < (sz - 1); ++i) {
+      ifaces_[i]->testNamespaceClassLoad(login, namespaceName, className, asTypeName);
+    }
+    return ifaces_[i]->testNamespaceClassLoad(login, namespaceName, className, asTypeName);
+  }
+
 };
 
+// The 'concurrent' client is a thread safe client that correctly handles
+// out of order responses.  It is slower than the regular client, so should
+// only be used when you need to share a connection among multiple threads
+class AccumuloProxyConcurrentClient : virtual public AccumuloProxyIf {
+ public:
+  AccumuloProxyConcurrentClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+    setProtocol(prot);
+  }
+  AccumuloProxyConcurrentClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+    setProtocol(iprot,oprot);
+  }
+ private:
+  void setProtocol(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
+  setProtocol(prot,prot);
+  }
+  void setProtocol(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
+    piprot_=iprot;
+    poprot_=oprot;
+    iprot_ = iprot.get();
+    oprot_ = oprot.get();
+  }
+ public:
+  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
+    return piprot_;
+  }
+  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
+    return poprot_;
+  }
+  void login(std::string& _return, const std::string& principal, const std::map<std::string, std::string> & loginProperties);
+  int32_t send_login(const std::string& principal, const std::map<std::string, std::string> & loginProperties);
+  void recv_login(std::string& _return, const int32_t seqid);
+  int32_t addConstraint(const std::string& login, const std::string& tableName, const std::string& constraintClassName);
+  int32_t send_addConstraint(const std::string& login, const std::string& tableName, const std::string& constraintClassName);
+  int32_t recv_addConstraint(const int32_t seqid);
+  void addSplits(const std::string& login, const std::string& tableName, const std::set<std::string> & splits);
+  int32_t send_addSplits(const std::string& login, const std::string& tableName, const std::set<std::string> & splits);
+  void recv_addSplits(const int32_t seqid);
+  void attachIterator(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  int32_t send_attachIterator(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  void recv_attachIterator(const int32_t seqid);
+  void checkIteratorConflicts(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  int32_t send_checkIteratorConflicts(const std::string& login, const std::string& tableName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  void recv_checkIteratorConflicts(const int32_t seqid);
+  void clearLocatorCache(const std::string& login, const std::string& tableName);
+  int32_t send_clearLocatorCache(const std::string& login, const std::string& tableName);
+  void recv_clearLocatorCache(const int32_t seqid);
+  void cloneTable(const std::string& login, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude);
+  int32_t send_cloneTable(const std::string& login, const std::string& tableName, const std::string& newTableName, const bool flush, const std::map<std::string, std::string> & propertiesToSet, const std::set<std::string> & propertiesToExclude);
+  void recv_cloneTable(const int32_t seqid);
+  void compactTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const CompactionStrategyConfig& compactionStrategy);
+  int32_t send_compactTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const std::vector<IteratorSetting> & iterators, const bool flush, const bool wait, const CompactionStrategyConfig& compactionStrategy);
+  void recv_compactTable(const int32_t seqid);
+  void cancelCompaction(const std::string& login, const std::string& tableName);
+  int32_t send_cancelCompaction(const std::string& login, const std::string& tableName);
+  void recv_cancelCompaction(const int32_t seqid);
+  void createTable(const std::string& login, const std::string& tableName, const bool versioningIter, const TimeType::type type);
+  int32_t send_createTable(const std::string& login, const std::string& tableName, const bool versioningIter, const TimeType::type type);
+  void recv_createTable(const int32_t seqid);
+  void deleteTable(const std::string& login, const std::string& tableName);
+  int32_t send_deleteTable(const std::string& login, const std::string& tableName);
+  void recv_deleteTable(const int32_t seqid);
+  void deleteRows(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
+  int32_t send_deleteRows(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
+  void recv_deleteRows(const int32_t seqid);
+  void exportTable(const std::string& login, const std::string& tableName, const std::string& exportDir);
+  int32_t send_exportTable(const std::string& login, const std::string& tableName, const std::string& exportDir);
+  void recv_exportTable(const int32_t seqid);
+  void flushTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait);
+  int32_t send_flushTable(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow, const bool wait);
+  void recv_flushTable(const int32_t seqid);
+  void getDiskUsage(std::vector<DiskUsage> & _return, const std::string& login, const std::set<std::string> & tables);
+  int32_t send_getDiskUsage(const std::string& login, const std::set<std::string> & tables);
+  void recv_getDiskUsage(std::vector<DiskUsage> & _return, const int32_t seqid);
+  void getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const std::string& login, const std::string& tableName);
+  int32_t send_getLocalityGroups(const std::string& login, const std::string& tableName);
+  void recv_getLocalityGroups(std::map<std::string, std::set<std::string> > & _return, const int32_t seqid);
+  void getIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope);
+  int32_t send_getIteratorSetting(const std::string& login, const std::string& tableName, const std::string& iteratorName, const IteratorScope::type scope);
+  void recv_getIteratorSetting(IteratorSetting& _return, const int32_t seqid);
+  void getMaxRow(std::string& _return, const std::string& login, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive);
+  int32_t send_getMaxRow(const std::string& login, const std::string& tableName, const std::set<std::string> & auths, const std::string& startRow, const bool startInclusive, const std::string& endRow, const bool endInclusive);
+  void recv_getMaxRow(std::string& _return, const int32_t seqid);
+  void getTableProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& tableName);
+  int32_t send_getTableProperties(const std::string& login, const std::string& tableName);
+  void recv_getTableProperties(std::map<std::string, std::string> & _return, const int32_t seqid);
+  void importDirectory(const std::string& login, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime);
+  int32_t send_importDirectory(const std::string& login, const std::string& tableName, const std::string& importDir, const std::string& failureDir, const bool setTime);
+  void recv_importDirectory(const int32_t seqid);
+  void importTable(const std::string& login, const std::string& tableName, const std::string& importDir);
+  int32_t send_importTable(const std::string& login, const std::string& tableName, const std::string& importDir);
+  void recv_importTable(const int32_t seqid);
+  void listSplits(std::vector<std::string> & _return, const std::string& login, const std::string& tableName, const int32_t maxSplits);
+  int32_t send_listSplits(const std::string& login, const std::string& tableName, const int32_t maxSplits);
+  void recv_listSplits(std::vector<std::string> & _return, const int32_t seqid);
+  void listTables(std::set<std::string> & _return, const std::string& login);
+  int32_t send_listTables(const std::string& login);
+  void recv_listTables(std::set<std::string> & _return, const int32_t seqid);
+  void listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& tableName);
+  int32_t send_listIterators(const std::string& login, const std::string& tableName);
+  void recv_listIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const int32_t seqid);
+  void listConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& tableName);
+  int32_t send_listConstraints(const std::string& login, const std::string& tableName);
+  void recv_listConstraints(std::map<std::string, int32_t> & _return, const int32_t seqid);
+  void mergeTablets(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
+  int32_t send_mergeTablets(const std::string& login, const std::string& tableName, const std::string& startRow, const std::string& endRow);
+  void recv_mergeTablets(const int32_t seqid);
+  void offlineTable(const std::string& login, const std::string& tableName, const bool wait);
+  int32_t send_offlineTable(const std::string& login, const std::string& tableName, const bool wait);
+  void recv_offlineTable(const int32_t seqid);
+  void onlineTable(const std::string& login, const std::string& tableName, const bool wait);
+  int32_t send_onlineTable(const std::string& login, const std::string& tableName, const bool wait);
+  void recv_onlineTable(const int32_t seqid);
+  void removeConstraint(const std::string& login, const std::string& tableName, const int32_t constraint);
+  int32_t send_removeConstraint(const std::string& login, const std::string& tableName, const int32_t constraint);
+  void recv_removeConstraint(const int32_t seqid);
+  void removeIterator(const std::string& login, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes);
+  int32_t send_removeIterator(const std::string& login, const std::string& tableName, const std::string& iterName, const std::set<IteratorScope::type> & scopes);
+  void recv_removeIterator(const int32_t seqid);
+  void removeTableProperty(const std::string& login, const std::string& tableName, const std::string& property);
+  int32_t send_removeTableProperty(const std::string& login, const std::string& tableName, const std::string& property);
+  void recv_removeTableProperty(const int32_t seqid);
+  void renameTable(const std::string& login, const std::string& oldTableName, const std::string& newTableName);
+  int32_t send_renameTable(const std::string& login, const std::string& oldTableName, const std::string& newTableName);
+  void recv_renameTable(const int32_t seqid);
+  void setLocalityGroups(const std::string& login, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups);
+  int32_t send_setLocalityGroups(const std::string& login, const std::string& tableName, const std::map<std::string, std::set<std::string> > & groups);
+  void recv_setLocalityGroups(const int32_t seqid);
+  void setTableProperty(const std::string& login, const std::string& tableName, const std::string& property, const std::string& value);
+  int32_t send_setTableProperty(const std::string& login, const std::string& tableName, const std::string& property, const std::string& value);
+  void recv_setTableProperty(const int32_t seqid);
+  void splitRangeByTablets(std::set<Range> & _return, const std::string& login, const std::string& tableName, const Range& range, const int32_t maxSplits);
+  int32_t send_splitRangeByTablets(const std::string& login, const std::string& tableName, const Range& range, const int32_t maxSplits);
+  void recv_splitRangeByTablets(std::set<Range> & _return, const int32_t seqid);
+  bool tableExists(const std::string& login, const std::string& tableName);
+  int32_t send_tableExists(const std::string& login, const std::string& tableName);
+  bool recv_tableExists(const int32_t seqid);
+  void tableIdMap(std::map<std::string, std::string> & _return, const std::string& login);
+  int32_t send_tableIdMap(const std::string& login);
+  void recv_tableIdMap(std::map<std::string, std::string> & _return, const int32_t seqid);
+  bool testTableClassLoad(const std::string& login, const std::string& tableName, const std::string& className, const std::string& asTypeName);
+  int32_t send_testTableClassLoad(const std::string& login, const std::string& tableName, const std::string& className, const std::string& asTypeName);
+  bool recv_testTableClassLoad(const int32_t seqid);
+  void pingTabletServer(const std::string& login, const std::string& tserver);
+  int32_t send_pingTabletServer(const std::string& login, const std::string& tserver);
+  void recv_pingTabletServer(const int32_t seqid);
+  void getActiveScans(std::vector<ActiveScan> & _return, const std::string& login, const std::string& tserver);
+  int32_t send_getActiveScans(const std::string& login, const std::string& tserver);
+  void recv_getActiveScans(std::vector<ActiveScan> & _return, const int32_t seqid);
+  void getActiveCompactions(std::vector<ActiveCompaction> & _return, const std::string& login, const std::string& tserver);
+  int32_t send_getActiveCompactions(const std::string& login, const std::string& tserver);
+  void recv_getActiveCompactions(std::vector<ActiveCompaction> & _return, const int32_t seqid);
+  void getSiteConfiguration(std::map<std::string, std::string> & _return, const std::string& login);
+  int32_t send_getSiteConfiguration(const std::string& login);
+  void recv_getSiteConfiguration(std::map<std::string, std::string> & _return, const int32_t seqid);
+  void getSystemConfiguration(std::map<std::string, std::string> & _return, const std::string& login);
+  int32_t send_getSystemConfiguration(const std::string& login);
+  void recv_getSystemConfiguration(std::map<std::string, std::string> & _return, const int32_t seqid);
+  void getTabletServers(std::vector<std::string> & _return, const std::string& login);
+  int32_t send_getTabletServers(const std::string& login);
+  void recv_getTabletServers(std::vector<std::string> & _return, const int32_t seqid);
+  void removeProperty(const std::string& login, const std::string& property);
+  int32_t send_removeProperty(const std::string& login, const std::string& property);
+  void recv_removeProperty(const int32_t seqid);
+  void setProperty(const std::string& login, const std::string& property, const std::string& value);
+  int32_t send_setProperty(const std::string& login, const std::string& property, const std::string& value);
+  void recv_setProperty(const int32_t seqid);
+  bool testClassLoad(const std::string& login, const std::string& className, const std::string& asTypeName);
+  int32_t send_testClassLoad(const std::string& login, const std::string& className, const std::string& asTypeName);
+  bool recv_testClassLoad(const int32_t seqid);
+  bool authenticateUser(const std::string& login, const std::string& user, const std::map<std::string, std::string> & properties);
+  int32_t send_authenticateUser(const std::string& login, const std::string& user, const std::map<std::string, std::string> & properties);
+  bool recv_authenticateUser(const int32_t seqid);
+  void changeUserAuthorizations(const std::string& login, const std::string& user, const std::set<std::string> & authorizations);
+  int32_t send_changeUserAuthorizations(const std::string& login, const std::string& user, const std::set<std::string> & authorizations);
+  void recv_changeUserAuthorizations(const int32_t seqid);
+  void changeLocalUserPassword(const std::string& login, const std::string& user, const std::string& password);
+  int32_t send_changeLocalUserPassword(const std::string& login, const std::string& user, const std::string& password);
+  void recv_changeLocalUserPassword(const int32_t seqid);
+  void createLocalUser(const std::string& login, const std::string& user, const std::string& password);
+  int32_t send_createLocalUser(const std::string& login, const std::string& user, const std::string& password);
+  void recv_createLocalUser(const int32_t seqid);
+  void dropLocalUser(const std::string& login, const std::string& user);
+  int32_t send_dropLocalUser(const std::string& login, const std::string& user);
+  void recv_dropLocalUser(const int32_t seqid);
+  void getUserAuthorizations(std::vector<std::string> & _return, const std::string& login, const std::string& user);
+  int32_t send_getUserAuthorizations(const std::string& login, const std::string& user);
+  void recv_getUserAuthorizations(std::vector<std::string> & _return, const int32_t seqid);
+  void grantSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
+  int32_t send_grantSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
+  void recv_grantSystemPermission(const int32_t seqid);
+  void grantTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
+  int32_t send_grantTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
+  void recv_grantTablePermission(const int32_t seqid);
+  bool hasSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
+  int32_t send_hasSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
+  bool recv_hasSystemPermission(const int32_t seqid);
+  bool hasTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
+  int32_t send_hasTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
+  bool recv_hasTablePermission(const int32_t seqid);
+  void listLocalUsers(std::set<std::string> & _return, const std::string& login);
+  int32_t send_listLocalUsers(const std::string& login);
+  void recv_listLocalUsers(std::set<std::string> & _return, const int32_t seqid);
+  void revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
+  int32_t send_revokeSystemPermission(const std::string& login, const std::string& user, const SystemPermission::type perm);
+  void recv_revokeSystemPermission(const int32_t seqid);
+  void revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
+  int32_t send_revokeTablePermission(const std::string& login, const std::string& user, const std::string& table, const TablePermission::type perm);
+  void recv_revokeTablePermission(const int32_t seqid);
+  void grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  int32_t send_grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  void recv_grantNamespacePermission(const int32_t seqid);
+  bool hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  int32_t send_hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  bool recv_hasNamespacePermission(const int32_t seqid);
+  void revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  int32_t send_revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm);
+  void recv_revokeNamespacePermission(const int32_t seqid);
+  void createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options);
+  int32_t send_createBatchScanner(const std::string& login, const std::string& tableName, const BatchScanOptions& options);
+  void recv_createBatchScanner(std::string& _return, const int32_t seqid);
+  void createScanner(std::string& _return, const std::string& login, const std::string& tableName, const ScanOptions& options);
+  int32_t send_createScanner(const std::string& login, const std::string& tableName, const ScanOptions& options);
+  void recv_createScanner(std::string& _return, const int32_t seqid);
+  bool hasNext(const std::string& scanner);
+  int32_t send_hasNext(const std::string& scanner);
+  bool recv_hasNext(const int32_t seqid);
+  void nextEntry(KeyValueAndPeek& _return, const std::string& scanner);
+  int32_t send_nextEntry(const std::string& scanner);
+  void recv_nextEntry(KeyValueAndPeek& _return, const int32_t seqid);
+  void nextK(ScanResult& _return, const std::string& scanner, const int32_t k);
+  int32_t send_nextK(const std::string& scanner, const int32_t k);
+  void recv_nextK(ScanResult& _return, const int32_t seqid);
+  void closeScanner(const std::string& scanner);
+  int32_t send_closeScanner(const std::string& scanner);
+  void recv_closeScanner(const int32_t seqid);
+  void updateAndFlush(const std::string& login, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
+  int32_t send_updateAndFlush(const std::string& login, const std::string& tableName, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
+  void recv_updateAndFlush(const int32_t seqid);
+  void createWriter(std::string& _return, const std::string& login, const std::string& tableName, const WriterOptions& opts);
+  int32_t send_createWriter(const std::string& login, const std::string& tableName, const WriterOptions& opts);
+  void recv_createWriter(std::string& _return, const int32_t seqid);
+  void update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
+  void send_update(const std::string& writer, const std::map<std::string, std::vector<ColumnUpdate> > & cells);
+  void flush(const std::string& writer);
+  int32_t send_flush(const std::string& writer);
+  void recv_flush(const int32_t seqid);
+  void closeWriter(const std::string& writer);
+  int32_t send_closeWriter(const std::string& writer);
+  void recv_closeWriter(const int32_t seqid);
+  ConditionalStatus::type updateRowConditionally(const std::string& login, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates);
+  int32_t send_updateRowConditionally(const std::string& login, const std::string& tableName, const std::string& row, const ConditionalUpdates& updates);
+  ConditionalStatus::type recv_updateRowConditionally(const int32_t seqid);
+  void createConditionalWriter(std::string& _return, const std::string& login, const std::string& tableName, const ConditionalWriterOptions& options);
+  int32_t send_createConditionalWriter(const std::string& login, const std::string& tableName, const ConditionalWriterOptions& options);
+  void recv_createConditionalWriter(std::string& _return, const int32_t seqid);
+  void updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates);
+  int32_t send_updateRowsConditionally(const std::string& conditionalWriter, const std::map<std::string, ConditionalUpdates> & updates);
+  void recv_updateRowsConditionally(std::map<std::string, ConditionalStatus::type> & _return, const int32_t seqid);
+  void closeConditionalWriter(const std::string& conditionalWriter);
+  int32_t send_closeConditionalWriter(const std::string& conditionalWriter);
+  void recv_closeConditionalWriter(const int32_t seqid);
+  void getRowRange(Range& _return, const std::string& row);
+  int32_t send_getRowRange(const std::string& row);
+  void recv_getRowRange(Range& _return, const int32_t seqid);
+  void getFollowing(Key& _return, const Key& key, const PartialKey::type part);
+  int32_t send_getFollowing(const Key& key, const PartialKey::type part);
+  void recv_getFollowing(Key& _return, const int32_t seqid);
+  void systemNamespace(std::string& _return);
+  int32_t send_systemNamespace();
+  void recv_systemNamespace(std::string& _return, const int32_t seqid);
+  void defaultNamespace(std::string& _return);
+  int32_t send_defaultNamespace();
+  void recv_defaultNamespace(std::string& _return, const int32_t seqid);
+  void listNamespaces(std::vector<std::string> & _return, const std::string& login);
+  int32_t send_listNamespaces(const std::string& login);
+  void recv_listNamespaces(std::vector<std::string> & _return, const int32_t seqid);
+  bool namespaceExists(const std::string& login, const std::string& namespaceName);
+  int32_t send_namespaceExists(const std::string& login, const std::string& namespaceName);
+  bool recv_namespaceExists(const int32_t seqid);
+  void createNamespace(const std::string& login, const std::string& namespaceName);
+  int32_t send_createNamespace(const std::string& login, const std::string& namespaceName);
+  void recv_createNamespace(const int32_t seqid);
+  void deleteNamespace(const std::string& login, const std::string& namespaceName);
+  int32_t send_deleteNamespace(const std::string& login, const std::string& namespaceName);
+  void recv_deleteNamespace(const int32_t seqid);
+  void renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName);
+  int32_t send_renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName);
+  void recv_renameNamespace(const int32_t seqid);
+  void setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value);
+  int32_t send_setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value);
+  void recv_setNamespaceProperty(const int32_t seqid);
+  void removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property);
+  int32_t send_removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property);
+  void recv_removeNamespaceProperty(const int32_t seqid);
+  void getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName);
+  int32_t send_getNamespaceProperties(const std::string& login, const std::string& namespaceName);
+  void recv_getNamespaceProperties(std::map<std::string, std::string> & _return, const int32_t seqid);
+  void namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login);
+  int32_t send_namespaceIdMap(const std::string& login);
+  void recv_namespaceIdMap(std::map<std::string, std::string> & _return, const int32_t seqid);
+  void attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  int32_t send_attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  void recv_attachNamespaceIterator(const int32_t seqid);
+  void removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes);
+  int32_t send_removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes);
+  void recv_removeNamespaceIterator(const int32_t seqid);
+  void getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope);
+  int32_t send_getNamespaceIteratorSetting(const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope);
+  void recv_getNamespaceIteratorSetting(IteratorSetting& _return, const int32_t seqid);
+  void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName);
+  int32_t send_listNamespaceIterators(const std::string& login, const std::string& namespaceName);
+  void recv_listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const int32_t seqid);
+  void checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  int32_t send_checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes);
+  void recv_checkNamespaceIteratorConflicts(const int32_t seqid);
+  int32_t addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName);
+  int32_t send_addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName);
+  int32_t recv_addNamespaceConstraint(const int32_t seqid);
+  void removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id);
+  int32_t send_removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id);
+  void recv_removeNamespaceConstraint(const int32_t seqid);
+  void listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName);
+  int32_t send_listNamespaceConstraints(const std::string& login, const std::string& namespaceName);
+  void recv_listNamespaceConstraints(std::map<std::string, int32_t> & _return, const int32_t seqid);
+  bool testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName);
+  int32_t send_testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName);
+  bool recv_testNamespaceClassLoad(const int32_t seqid);
+ protected:
+  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
+  boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
+  ::apache::thrift::protocol::TProtocol* iprot_;
+  ::apache::thrift::protocol::TProtocol* oprot_;
+  ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
+};
+
+#ifdef _WIN32
+  #pragma warning( pop )
+#endif
+
 } // namespace
 
 #endif
diff --git a/src/main/cpp/AccumuloProxy_server.skeleton.cpp b/src/main/cpp/AccumuloProxy_server.skeleton.cpp
index 302aec2..6c2f52f 100644
--- a/src/main/cpp/AccumuloProxy_server.skeleton.cpp
+++ b/src/main/cpp/AccumuloProxy_server.skeleton.cpp
@@ -338,6 +338,21 @@
     printf("revokeTablePermission\n");
   }
 
+  void grantNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) {
+    // Your implementation goes here
+    printf("grantNamespacePermission\n");
+  }
+
+  bool hasNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) {
+    // Your implementation goes here
+    printf("hasNamespacePermission\n");
+  }
+
+  void revokeNamespacePermission(const std::string& login, const std::string& user, const std::string& namespaceName, const NamespacePermission::type perm) {
+    // Your implementation goes here
+    printf("revokeNamespacePermission\n");
+  }
+
   void createBatchScanner(std::string& _return, const std::string& login, const std::string& tableName, const BatchScanOptions& options) {
     // Your implementation goes here
     printf("createBatchScanner\n");
@@ -423,6 +438,106 @@
     printf("getFollowing\n");
   }
 
+  void systemNamespace(std::string& _return) {
+    // Your implementation goes here
+    printf("systemNamespace\n");
+  }
+
+  void defaultNamespace(std::string& _return) {
+    // Your implementation goes here
+    printf("defaultNamespace\n");
+  }
+
+  void listNamespaces(std::vector<std::string> & _return, const std::string& login) {
+    // Your implementation goes here
+    printf("listNamespaces\n");
+  }
+
+  bool namespaceExists(const std::string& login, const std::string& namespaceName) {
+    // Your implementation goes here
+    printf("namespaceExists\n");
+  }
+
+  void createNamespace(const std::string& login, const std::string& namespaceName) {
+    // Your implementation goes here
+    printf("createNamespace\n");
+  }
+
+  void deleteNamespace(const std::string& login, const std::string& namespaceName) {
+    // Your implementation goes here
+    printf("deleteNamespace\n");
+  }
+
+  void renameNamespace(const std::string& login, const std::string& oldNamespaceName, const std::string& newNamespaceName) {
+    // Your implementation goes here
+    printf("renameNamespace\n");
+  }
+
+  void setNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property, const std::string& value) {
+    // Your implementation goes here
+    printf("setNamespaceProperty\n");
+  }
+
+  void removeNamespaceProperty(const std::string& login, const std::string& namespaceName, const std::string& property) {
+    // Your implementation goes here
+    printf("removeNamespaceProperty\n");
+  }
+
+  void getNamespaceProperties(std::map<std::string, std::string> & _return, const std::string& login, const std::string& namespaceName) {
+    // Your implementation goes here
+    printf("getNamespaceProperties\n");
+  }
+
+  void namespaceIdMap(std::map<std::string, std::string> & _return, const std::string& login) {
+    // Your implementation goes here
+    printf("namespaceIdMap\n");
+  }
+
+  void attachNamespaceIterator(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) {
+    // Your implementation goes here
+    printf("attachNamespaceIterator\n");
+  }
+
+  void removeNamespaceIterator(const std::string& login, const std::string& namespaceName, const std::string& name, const std::set<IteratorScope::type> & scopes) {
+    // Your implementation goes here
+    printf("removeNamespaceIterator\n");
+  }
+
+  void getNamespaceIteratorSetting(IteratorSetting& _return, const std::string& login, const std::string& namespaceName, const std::string& name, const IteratorScope::type scope) {
+    // Your implementation goes here
+    printf("getNamespaceIteratorSetting\n");
+  }
+
+  void listNamespaceIterators(std::map<std::string, std::set<IteratorScope::type> > & _return, const std::string& login, const std::string& namespaceName) {
+    // Your implementation goes here
+    printf("listNamespaceIterators\n");
+  }
+
+  void checkNamespaceIteratorConflicts(const std::string& login, const std::string& namespaceName, const IteratorSetting& setting, const std::set<IteratorScope::type> & scopes) {
+    // Your implementation goes here
+    printf("checkNamespaceIteratorConflicts\n");
+  }
+
+  int32_t addNamespaceConstraint(const std::string& login, const std::string& namespaceName, const std::string& constraintClassName) {
+    // Your implementation goes here
+    printf("addNamespaceConstraint\n");
+  }
+
+  void removeNamespaceConstraint(const std::string& login, const std::string& namespaceName, const int32_t id) {
+    // Your implementation goes here
+    printf("removeNamespaceConstraint\n");
+  }
+
+  void listNamespaceConstraints(std::map<std::string, int32_t> & _return, const std::string& login, const std::string& namespaceName) {
+    // Your implementation goes here
+    printf("listNamespaceConstraints\n");
+  }
+
+  bool testNamespaceClassLoad(const std::string& login, const std::string& namespaceName, const std::string& className, const std::string& asTypeName) {
+    // Your implementation goes here
+    printf("testNamespaceClassLoad\n");
+  }
+
 };
 
 int main(int argc, char **argv) {
diff --git a/src/main/cpp/proxy_constants.cpp b/src/main/cpp/proxy_constants.cpp
index 39a574e..d177867 100644
--- a/src/main/cpp/proxy_constants.cpp
+++ b/src/main/cpp/proxy_constants.cpp
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/cpp/proxy_constants.h b/src/main/cpp/proxy_constants.h
index 8f789c6..c2d6fd6 100644
--- a/src/main/cpp/proxy_constants.h
+++ b/src/main/cpp/proxy_constants.h
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/cpp/proxy_types.cpp b/src/main/cpp/proxy_types.cpp
index 4a626f5..87ef7ac 100644
--- a/src/main/cpp/proxy_types.cpp
+++ b/src/main/cpp/proxy_types.cpp
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,6 +23,9 @@
 #include "proxy_types.h"
 
 #include <algorithm>
+#include <ostream>
+
+#include <thrift/TToString.h>
 
 namespace accumulo {
 
@@ -92,6 +95,30 @@
 };
 const std::map<int, const char*> _SystemPermission_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(12, _kSystemPermissionValues, _kSystemPermissionNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
 
+int _kNamespacePermissionValues[] = {
+  NamespacePermission::READ,
+  NamespacePermission::WRITE,
+  NamespacePermission::ALTER_NAMESPACE,
+  NamespacePermission::GRANT,
+  NamespacePermission::ALTER_TABLE,
+  NamespacePermission::CREATE_TABLE,
+  NamespacePermission::DROP_TABLE,
+  NamespacePermission::BULK_IMPORT,
+  NamespacePermission::DROP_NAMESPACE
+};
+const char* _kNamespacePermissionNames[] = {
+  "READ",
+  "WRITE",
+  "ALTER_NAMESPACE",
+  "GRANT",
+  "ALTER_TABLE",
+  "CREATE_TABLE",
+  "DROP_TABLE",
+  "BULK_IMPORT",
+  "DROP_NAMESPACE"
+};
+const std::map<int, const char*> _NamespacePermission_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(9, _kNamespacePermissionValues, _kNamespacePermissionNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
+
 int _kScanTypeValues[] = {
   ScanType::SINGLE,
   ScanType::BATCH
@@ -198,11 +225,35 @@
 };
 const std::map<int, const char*> _TimeType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(2, _kTimeTypeValues, _kTimeTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
 
-const char* Key::ascii_fingerprint = "91151A432E03F5E8564877B5194B48E2";
-const uint8_t Key::binary_fingerprint[16] = {0x91,0x15,0x1A,0x43,0x2E,0x03,0xF5,0xE8,0x56,0x48,0x77,0xB5,0x19,0x4B,0x48,0xE2};
+
+Key::~Key() throw() {
+}
+
+
+void Key::__set_row(const std::string& val) {
+  this->row = val;
+}
+
+void Key::__set_colFamily(const std::string& val) {
+  this->colFamily = val;
+}
+
+void Key::__set_colQualifier(const std::string& val) {
+  this->colQualifier = val;
+}
+
+void Key::__set_colVisibility(const std::string& val) {
+  this->colVisibility = val;
+}
+
+void Key::__set_timestamp(const int64_t val) {
+  this->timestamp = val;
+__isset.timestamp = true;
+}
 
 uint32_t Key::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -275,6 +326,7 @@
 
 uint32_t Key::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("Key");
 
   xfer += oprot->writeFieldBegin("row", ::apache::thrift::protocol::T_STRING, 1);
@@ -313,11 +365,70 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* ColumnUpdate::ascii_fingerprint = "65CC1863F7DDC1DE75B9EAF9E2DC0D1F";
-const uint8_t ColumnUpdate::binary_fingerprint[16] = {0x65,0xCC,0x18,0x63,0xF7,0xDD,0xC1,0xDE,0x75,0xB9,0xEA,0xF9,0xE2,0xDC,0x0D,0x1F};
+Key::Key(const Key& other0) {
+  row = other0.row;
+  colFamily = other0.colFamily;
+  colQualifier = other0.colQualifier;
+  colVisibility = other0.colVisibility;
+  timestamp = other0.timestamp;
+  __isset = other0.__isset;
+}
+Key& Key::operator=(const Key& other1) {
+  row = other1.row;
+  colFamily = other1.colFamily;
+  colQualifier = other1.colQualifier;
+  colVisibility = other1.colVisibility;
+  timestamp = other1.timestamp;
+  __isset = other1.__isset;
+  return *this;
+}
+void Key::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "Key(";
+  out << "row=" << to_string(row);
+  out << ", " << "colFamily=" << to_string(colFamily);
+  out << ", " << "colQualifier=" << to_string(colQualifier);
+  out << ", " << "colVisibility=" << to_string(colVisibility);
+  out << ", " << "timestamp="; (__isset.timestamp ? (out << to_string(timestamp)) : (out << "<null>"));
+  out << ")";
+}
+
+
+ColumnUpdate::~ColumnUpdate() throw() {
+}
+
+
+void ColumnUpdate::__set_colFamily(const std::string& val) {
+  this->colFamily = val;
+}
+
+void ColumnUpdate::__set_colQualifier(const std::string& val) {
+  this->colQualifier = val;
+}
+
+void ColumnUpdate::__set_colVisibility(const std::string& val) {
+  this->colVisibility = val;
+__isset.colVisibility = true;
+}
+
+void ColumnUpdate::__set_timestamp(const int64_t val) {
+  this->timestamp = val;
+__isset.timestamp = true;
+}
+
+void ColumnUpdate::__set_value(const std::string& val) {
+  this->value = val;
+__isset.value = true;
+}
+
+void ColumnUpdate::__set_deleteCell(const bool val) {
+  this->deleteCell = val;
+__isset.deleteCell = true;
+}
 
 uint32_t ColumnUpdate::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -398,6 +509,7 @@
 
 uint32_t ColumnUpdate::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("ColumnUpdate");
 
   xfer += oprot->writeFieldBegin("colFamily", ::apache::thrift::protocol::T_STRING, 1);
@@ -444,11 +556,53 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* DiskUsage::ascii_fingerprint = "D26F4F5E2867D41CF7E0391263932D6B";
-const uint8_t DiskUsage::binary_fingerprint[16] = {0xD2,0x6F,0x4F,0x5E,0x28,0x67,0xD4,0x1C,0xF7,0xE0,0x39,0x12,0x63,0x93,0x2D,0x6B};
+ColumnUpdate::ColumnUpdate(const ColumnUpdate& other2) {
+  colFamily = other2.colFamily;
+  colQualifier = other2.colQualifier;
+  colVisibility = other2.colVisibility;
+  timestamp = other2.timestamp;
+  value = other2.value;
+  deleteCell = other2.deleteCell;
+  __isset = other2.__isset;
+}
+ColumnUpdate& ColumnUpdate::operator=(const ColumnUpdate& other3) {
+  colFamily = other3.colFamily;
+  colQualifier = other3.colQualifier;
+  colVisibility = other3.colVisibility;
+  timestamp = other3.timestamp;
+  value = other3.value;
+  deleteCell = other3.deleteCell;
+  __isset = other3.__isset;
+  return *this;
+}
+void ColumnUpdate::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "ColumnUpdate(";
+  out << "colFamily=" << to_string(colFamily);
+  out << ", " << "colQualifier=" << to_string(colQualifier);
+  out << ", " << "colVisibility="; (__isset.colVisibility ? (out << to_string(colVisibility)) : (out << "<null>"));
+  out << ", " << "timestamp="; (__isset.timestamp ? (out << to_string(timestamp)) : (out << "<null>"));
+  out << ", " << "value="; (__isset.value ? (out << to_string(value)) : (out << "<null>"));
+  out << ", " << "deleteCell="; (__isset.deleteCell ? (out << to_string(deleteCell)) : (out << "<null>"));
+  out << ")";
+}
+
+
+DiskUsage::~DiskUsage() throw() {
+}
+
+
+void DiskUsage::__set_tables(const std::vector<std::string> & val) {
+  this->tables = val;
+}
+
+void DiskUsage::__set_usage(const int64_t val) {
+  this->usage = val;
+}
 
 uint32_t DiskUsage::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -471,14 +625,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->tables.clear();
-            uint32_t _size0;
-            ::apache::thrift::protocol::TType _etype3;
-            xfer += iprot->readListBegin(_etype3, _size0);
-            this->tables.resize(_size0);
-            uint32_t _i4;
-            for (_i4 = 0; _i4 < _size0; ++_i4)
+            uint32_t _size4;
+            ::apache::thrift::protocol::TType _etype7;
+            xfer += iprot->readListBegin(_etype7, _size4);
+            this->tables.resize(_size4);
+            uint32_t _i8;
+            for (_i8 = 0; _i8 < _size4; ++_i8)
             {
-              xfer += iprot->readString(this->tables[_i4]);
+              xfer += iprot->readString(this->tables[_i8]);
             }
             xfer += iprot->readListEnd();
           }
@@ -509,15 +663,16 @@
 
 uint32_t DiskUsage::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("DiskUsage");
 
   xfer += oprot->writeFieldBegin("tables", ::apache::thrift::protocol::T_LIST, 1);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->tables.size()));
-    std::vector<std::string> ::const_iterator _iter5;
-    for (_iter5 = this->tables.begin(); _iter5 != this->tables.end(); ++_iter5)
+    std::vector<std::string> ::const_iterator _iter9;
+    for (_iter9 = this->tables.begin(); _iter9 != this->tables.end(); ++_iter9)
     {
-      xfer += oprot->writeString((*_iter5));
+      xfer += oprot->writeString((*_iter9));
     }
     xfer += oprot->writeListEnd();
   }
@@ -539,11 +694,41 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* KeyValue::ascii_fingerprint = "0D0CA44F233F983E00E94228C31ABBD4";
-const uint8_t KeyValue::binary_fingerprint[16] = {0x0D,0x0C,0xA4,0x4F,0x23,0x3F,0x98,0x3E,0x00,0xE9,0x42,0x28,0xC3,0x1A,0xBB,0xD4};
+DiskUsage::DiskUsage(const DiskUsage& other10) {
+  tables = other10.tables;
+  usage = other10.usage;
+  __isset = other10.__isset;
+}
+DiskUsage& DiskUsage::operator=(const DiskUsage& other11) {
+  tables = other11.tables;
+  usage = other11.usage;
+  __isset = other11.__isset;
+  return *this;
+}
+void DiskUsage::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "DiskUsage(";
+  out << "tables=" << to_string(tables);
+  out << ", " << "usage=" << to_string(usage);
+  out << ")";
+}
+
+
+KeyValue::~KeyValue() throw() {
+}
+
+
+void KeyValue::__set_key(const Key& val) {
+  this->key = val;
+}
+
+void KeyValue::__set_value(const std::string& val) {
+  this->value = val;
+}
 
 uint32_t KeyValue::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -592,6 +777,7 @@
 
 uint32_t KeyValue::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("KeyValue");
 
   xfer += oprot->writeFieldBegin("key", ::apache::thrift::protocol::T_STRUCT, 1);
@@ -614,11 +800,41 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* ScanResult::ascii_fingerprint = "684A3FCA76EA202FE071A17F8B510E7A";
-const uint8_t ScanResult::binary_fingerprint[16] = {0x68,0x4A,0x3F,0xCA,0x76,0xEA,0x20,0x2F,0xE0,0x71,0xA1,0x7F,0x8B,0x51,0x0E,0x7A};
+KeyValue::KeyValue(const KeyValue& other12) {
+  key = other12.key;
+  value = other12.value;
+  __isset = other12.__isset;
+}
+KeyValue& KeyValue::operator=(const KeyValue& other13) {
+  key = other13.key;
+  value = other13.value;
+  __isset = other13.__isset;
+  return *this;
+}
+void KeyValue::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "KeyValue(";
+  out << "key=" << to_string(key);
+  out << ", " << "value=" << to_string(value);
+  out << ")";
+}
+
+
+ScanResult::~ScanResult() throw() {
+}
+
+
+void ScanResult::__set_results(const std::vector<KeyValue> & val) {
+  this->results = val;
+}
+
+void ScanResult::__set_more(const bool val) {
+  this->more = val;
+}
 
 uint32_t ScanResult::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -641,14 +857,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->results.clear();
-            uint32_t _size6;
-            ::apache::thrift::protocol::TType _etype9;
-            xfer += iprot->readListBegin(_etype9, _size6);
-            this->results.resize(_size6);
-            uint32_t _i10;
-            for (_i10 = 0; _i10 < _size6; ++_i10)
+            uint32_t _size14;
+            ::apache::thrift::protocol::TType _etype17;
+            xfer += iprot->readListBegin(_etype17, _size14);
+            this->results.resize(_size14);
+            uint32_t _i18;
+            for (_i18 = 0; _i18 < _size14; ++_i18)
             {
-              xfer += this->results[_i10].read(iprot);
+              xfer += this->results[_i18].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -679,15 +895,16 @@
 
 uint32_t ScanResult::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("ScanResult");
 
   xfer += oprot->writeFieldBegin("results", ::apache::thrift::protocol::T_LIST, 1);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->results.size()));
-    std::vector<KeyValue> ::const_iterator _iter11;
-    for (_iter11 = this->results.begin(); _iter11 != this->results.end(); ++_iter11)
+    std::vector<KeyValue> ::const_iterator _iter19;
+    for (_iter19 = this->results.begin(); _iter19 != this->results.end(); ++_iter19)
     {
-      xfer += (*_iter11).write(oprot);
+      xfer += (*_iter19).write(oprot);
     }
     xfer += oprot->writeListEnd();
   }
@@ -709,11 +926,49 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* Range::ascii_fingerprint = "84C5BA8DB718E60BFBF3F83867647B45";
-const uint8_t Range::binary_fingerprint[16] = {0x84,0xC5,0xBA,0x8D,0xB7,0x18,0xE6,0x0B,0xFB,0xF3,0xF8,0x38,0x67,0x64,0x7B,0x45};
+ScanResult::ScanResult(const ScanResult& other20) {
+  results = other20.results;
+  more = other20.more;
+  __isset = other20.__isset;
+}
+ScanResult& ScanResult::operator=(const ScanResult& other21) {
+  results = other21.results;
+  more = other21.more;
+  __isset = other21.__isset;
+  return *this;
+}
+void ScanResult::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "ScanResult(";
+  out << "results=" << to_string(results);
+  out << ", " << "more=" << to_string(more);
+  out << ")";
+}
+
+
+Range::~Range() throw() {
+}
+
+
+void Range::__set_start(const Key& val) {
+  this->start = val;
+}
+
+void Range::__set_startInclusive(const bool val) {
+  this->startInclusive = val;
+}
+
+void Range::__set_stop(const Key& val) {
+  this->stop = val;
+}
+
+void Range::__set_stopInclusive(const bool val) {
+  this->stopInclusive = val;
+}
 
 uint32_t Range::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -778,6 +1033,7 @@
 
 uint32_t Range::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("Range");
 
   xfer += oprot->writeFieldBegin("start", ::apache::thrift::protocol::T_STRUCT, 1);
@@ -810,11 +1066,48 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* ScanColumn::ascii_fingerprint = "5B708A954C550ECA9C1A49D3C5CAFAB9";
-const uint8_t ScanColumn::binary_fingerprint[16] = {0x5B,0x70,0x8A,0x95,0x4C,0x55,0x0E,0xCA,0x9C,0x1A,0x49,0xD3,0xC5,0xCA,0xFA,0xB9};
+Range::Range(const Range& other22) {
+  start = other22.start;
+  startInclusive = other22.startInclusive;
+  stop = other22.stop;
+  stopInclusive = other22.stopInclusive;
+  __isset = other22.__isset;
+}
+Range& Range::operator=(const Range& other23) {
+  start = other23.start;
+  startInclusive = other23.startInclusive;
+  stop = other23.stop;
+  stopInclusive = other23.stopInclusive;
+  __isset = other23.__isset;
+  return *this;
+}
+void Range::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "Range(";
+  out << "start=" << to_string(start);
+  out << ", " << "startInclusive=" << to_string(startInclusive);
+  out << ", " << "stop=" << to_string(stop);
+  out << ", " << "stopInclusive=" << to_string(stopInclusive);
+  out << ")";
+}
+
+
+ScanColumn::~ScanColumn() throw() {
+}
+
+
+void ScanColumn::__set_colFamily(const std::string& val) {
+  this->colFamily = val;
+}
+
+void ScanColumn::__set_colQualifier(const std::string& val) {
+  this->colQualifier = val;
+__isset.colQualifier = true;
+}
 
 uint32_t ScanColumn::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -863,6 +1156,7 @@
 
 uint32_t ScanColumn::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("ScanColumn");
 
   xfer += oprot->writeFieldBegin("colFamily", ::apache::thrift::protocol::T_STRING, 1);
@@ -886,11 +1180,49 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* IteratorSetting::ascii_fingerprint = "985C857916964E43205EAC92A157CB4E";
-const uint8_t IteratorSetting::binary_fingerprint[16] = {0x98,0x5C,0x85,0x79,0x16,0x96,0x4E,0x43,0x20,0x5E,0xAC,0x92,0xA1,0x57,0xCB,0x4E};
+ScanColumn::ScanColumn(const ScanColumn& other24) {
+  colFamily = other24.colFamily;
+  colQualifier = other24.colQualifier;
+  __isset = other24.__isset;
+}
+ScanColumn& ScanColumn::operator=(const ScanColumn& other25) {
+  colFamily = other25.colFamily;
+  colQualifier = other25.colQualifier;
+  __isset = other25.__isset;
+  return *this;
+}
+void ScanColumn::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "ScanColumn(";
+  out << "colFamily=" << to_string(colFamily);
+  out << ", " << "colQualifier="; (__isset.colQualifier ? (out << to_string(colQualifier)) : (out << "<null>"));
+  out << ")";
+}
+
+
+IteratorSetting::~IteratorSetting() throw() {
+}
+
+
+void IteratorSetting::__set_priority(const int32_t val) {
+  this->priority = val;
+}
+
+void IteratorSetting::__set_name(const std::string& val) {
+  this->name = val;
+}
+
+void IteratorSetting::__set_iteratorClass(const std::string& val) {
+  this->iteratorClass = val;
+}
+
+void IteratorSetting::__set_properties(const std::map<std::string, std::string> & val) {
+  this->properties = val;
+}
 
 uint32_t IteratorSetting::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -937,17 +1269,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->properties.clear();
-            uint32_t _size12;
-            ::apache::thrift::protocol::TType _ktype13;
-            ::apache::thrift::protocol::TType _vtype14;
-            xfer += iprot->readMapBegin(_ktype13, _vtype14, _size12);
-            uint32_t _i16;
-            for (_i16 = 0; _i16 < _size12; ++_i16)
+            uint32_t _size26;
+            ::apache::thrift::protocol::TType _ktype27;
+            ::apache::thrift::protocol::TType _vtype28;
+            xfer += iprot->readMapBegin(_ktype27, _vtype28, _size26);
+            uint32_t _i30;
+            for (_i30 = 0; _i30 < _size26; ++_i30)
             {
-              std::string _key17;
-              xfer += iprot->readString(_key17);
-              std::string& _val18 = this->properties[_key17];
-              xfer += iprot->readString(_val18);
+              std::string _key31;
+              xfer += iprot->readString(_key31);
+              std::string& _val32 = this->properties[_key31];
+              xfer += iprot->readString(_val32);
             }
             xfer += iprot->readMapEnd();
           }
@@ -970,6 +1302,7 @@
 
 uint32_t IteratorSetting::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("IteratorSetting");
 
   xfer += oprot->writeFieldBegin("priority", ::apache::thrift::protocol::T_I32, 1);
@@ -987,11 +1320,11 @@
   xfer += oprot->writeFieldBegin("properties", ::apache::thrift::protocol::T_MAP, 4);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->properties.size()));
-    std::map<std::string, std::string> ::const_iterator _iter19;
-    for (_iter19 = this->properties.begin(); _iter19 != this->properties.end(); ++_iter19)
+    std::map<std::string, std::string> ::const_iterator _iter33;
+    for (_iter33 = this->properties.begin(); _iter33 != this->properties.end(); ++_iter33)
     {
-      xfer += oprot->writeString(_iter19->first);
-      xfer += oprot->writeString(_iter19->second);
+      xfer += oprot->writeString(_iter33->first);
+      xfer += oprot->writeString(_iter33->second);
     }
     xfer += oprot->writeMapEnd();
   }
@@ -1011,11 +1344,64 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* ScanOptions::ascii_fingerprint = "3D87D0CD05FA62E15880C4D2C595907C";
-const uint8_t ScanOptions::binary_fingerprint[16] = {0x3D,0x87,0xD0,0xCD,0x05,0xFA,0x62,0xE1,0x58,0x80,0xC4,0xD2,0xC5,0x95,0x90,0x7C};
+IteratorSetting::IteratorSetting(const IteratorSetting& other34) {
+  priority = other34.priority;
+  name = other34.name;
+  iteratorClass = other34.iteratorClass;
+  properties = other34.properties;
+  __isset = other34.__isset;
+}
+IteratorSetting& IteratorSetting::operator=(const IteratorSetting& other35) {
+  priority = other35.priority;
+  name = other35.name;
+  iteratorClass = other35.iteratorClass;
+  properties = other35.properties;
+  __isset = other35.__isset;
+  return *this;
+}
+void IteratorSetting::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "IteratorSetting(";
+  out << "priority=" << to_string(priority);
+  out << ", " << "name=" << to_string(name);
+  out << ", " << "iteratorClass=" << to_string(iteratorClass);
+  out << ", " << "properties=" << to_string(properties);
+  out << ")";
+}
+
+
+ScanOptions::~ScanOptions() throw() {
+}
+
+
+void ScanOptions::__set_authorizations(const std::set<std::string> & val) {
+  this->authorizations = val;
+__isset.authorizations = true;
+}
+
+void ScanOptions::__set_range(const Range& val) {
+  this->range = val;
+__isset.range = true;
+}
+
+void ScanOptions::__set_columns(const std::vector<ScanColumn> & val) {
+  this->columns = val;
+__isset.columns = true;
+}
+
+void ScanOptions::__set_iterators(const std::vector<IteratorSetting> & val) {
+  this->iterators = val;
+__isset.iterators = true;
+}
+
+void ScanOptions::__set_bufferSize(const int32_t val) {
+  this->bufferSize = val;
+__isset.bufferSize = true;
+}
 
 uint32_t ScanOptions::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1038,15 +1424,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->authorizations.clear();
-            uint32_t _size20;
-            ::apache::thrift::protocol::TType _etype23;
-            xfer += iprot->readSetBegin(_etype23, _size20);
-            uint32_t _i24;
-            for (_i24 = 0; _i24 < _size20; ++_i24)
+            uint32_t _size36;
+            ::apache::thrift::protocol::TType _etype39;
+            xfer += iprot->readSetBegin(_etype39, _size36);
+            uint32_t _i40;
+            for (_i40 = 0; _i40 < _size36; ++_i40)
             {
-              std::string _elem25;
-              xfer += iprot->readBinary(_elem25);
-              this->authorizations.insert(_elem25);
+              std::string _elem41;
+              xfer += iprot->readBinary(_elem41);
+              this->authorizations.insert(_elem41);
             }
             xfer += iprot->readSetEnd();
           }
@@ -1067,14 +1453,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->columns.clear();
-            uint32_t _size26;
-            ::apache::thrift::protocol::TType _etype29;
-            xfer += iprot->readListBegin(_etype29, _size26);
-            this->columns.resize(_size26);
-            uint32_t _i30;
-            for (_i30 = 0; _i30 < _size26; ++_i30)
+            uint32_t _size42;
+            ::apache::thrift::protocol::TType _etype45;
+            xfer += iprot->readListBegin(_etype45, _size42);
+            this->columns.resize(_size42);
+            uint32_t _i46;
+            for (_i46 = 0; _i46 < _size42; ++_i46)
             {
-              xfer += this->columns[_i30].read(iprot);
+              xfer += this->columns[_i46].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -1087,14 +1473,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->iterators.clear();
-            uint32_t _size31;
-            ::apache::thrift::protocol::TType _etype34;
-            xfer += iprot->readListBegin(_etype34, _size31);
-            this->iterators.resize(_size31);
-            uint32_t _i35;
-            for (_i35 = 0; _i35 < _size31; ++_i35)
+            uint32_t _size47;
+            ::apache::thrift::protocol::TType _etype50;
+            xfer += iprot->readListBegin(_etype50, _size47);
+            this->iterators.resize(_size47);
+            uint32_t _i51;
+            for (_i51 = 0; _i51 < _size47; ++_i51)
             {
-              xfer += this->iterators[_i35].read(iprot);
+              xfer += this->iterators[_i51].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -1125,16 +1511,17 @@
 
 uint32_t ScanOptions::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("ScanOptions");
 
   if (this->__isset.authorizations) {
     xfer += oprot->writeFieldBegin("authorizations", ::apache::thrift::protocol::T_SET, 1);
     {
       xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->authorizations.size()));
-      std::set<std::string> ::const_iterator _iter36;
-      for (_iter36 = this->authorizations.begin(); _iter36 != this->authorizations.end(); ++_iter36)
+      std::set<std::string> ::const_iterator _iter52;
+      for (_iter52 = this->authorizations.begin(); _iter52 != this->authorizations.end(); ++_iter52)
       {
-        xfer += oprot->writeBinary((*_iter36));
+        xfer += oprot->writeBinary((*_iter52));
       }
       xfer += oprot->writeSetEnd();
     }
@@ -1149,10 +1536,10 @@
     xfer += oprot->writeFieldBegin("columns", ::apache::thrift::protocol::T_LIST, 3);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->columns.size()));
-      std::vector<ScanColumn> ::const_iterator _iter37;
-      for (_iter37 = this->columns.begin(); _iter37 != this->columns.end(); ++_iter37)
+      std::vector<ScanColumn> ::const_iterator _iter53;
+      for (_iter53 = this->columns.begin(); _iter53 != this->columns.end(); ++_iter53)
       {
-        xfer += (*_iter37).write(oprot);
+        xfer += (*_iter53).write(oprot);
       }
       xfer += oprot->writeListEnd();
     }
@@ -1162,10 +1549,10 @@
     xfer += oprot->writeFieldBegin("iterators", ::apache::thrift::protocol::T_LIST, 4);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->iterators.size()));
-      std::vector<IteratorSetting> ::const_iterator _iter38;
-      for (_iter38 = this->iterators.begin(); _iter38 != this->iterators.end(); ++_iter38)
+      std::vector<IteratorSetting> ::const_iterator _iter54;
+      for (_iter54 = this->iterators.begin(); _iter54 != this->iterators.end(); ++_iter54)
       {
-        xfer += (*_iter38).write(oprot);
+        xfer += (*_iter54).write(oprot);
       }
       xfer += oprot->writeListEnd();
     }
@@ -1191,11 +1578,67 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* BatchScanOptions::ascii_fingerprint = "6ADFA1FBE31B1220D2C103284E002308";
-const uint8_t BatchScanOptions::binary_fingerprint[16] = {0x6A,0xDF,0xA1,0xFB,0xE3,0x1B,0x12,0x20,0xD2,0xC1,0x03,0x28,0x4E,0x00,0x23,0x08};
+ScanOptions::ScanOptions(const ScanOptions& other55) {
+  authorizations = other55.authorizations;
+  range = other55.range;
+  columns = other55.columns;
+  iterators = other55.iterators;
+  bufferSize = other55.bufferSize;
+  __isset = other55.__isset;
+}
+ScanOptions& ScanOptions::operator=(const ScanOptions& other56) {
+  authorizations = other56.authorizations;
+  range = other56.range;
+  columns = other56.columns;
+  iterators = other56.iterators;
+  bufferSize = other56.bufferSize;
+  __isset = other56.__isset;
+  return *this;
+}
+void ScanOptions::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "ScanOptions(";
+  out << "authorizations="; (__isset.authorizations ? (out << to_string(authorizations)) : (out << "<null>"));
+  out << ", " << "range="; (__isset.range ? (out << to_string(range)) : (out << "<null>"));
+  out << ", " << "columns="; (__isset.columns ? (out << to_string(columns)) : (out << "<null>"));
+  out << ", " << "iterators="; (__isset.iterators ? (out << to_string(iterators)) : (out << "<null>"));
+  out << ", " << "bufferSize="; (__isset.bufferSize ? (out << to_string(bufferSize)) : (out << "<null>"));
+  out << ")";
+}
+
+
+BatchScanOptions::~BatchScanOptions() throw() {
+}
+
+
+void BatchScanOptions::__set_authorizations(const std::set<std::string> & val) {
+  this->authorizations = val;
+__isset.authorizations = true;
+}
+
+void BatchScanOptions::__set_ranges(const std::vector<Range> & val) {
+  this->ranges = val;
+__isset.ranges = true;
+}
+
+void BatchScanOptions::__set_columns(const std::vector<ScanColumn> & val) {
+  this->columns = val;
+__isset.columns = true;
+}
+
+void BatchScanOptions::__set_iterators(const std::vector<IteratorSetting> & val) {
+  this->iterators = val;
+__isset.iterators = true;
+}
+
+void BatchScanOptions::__set_threads(const int32_t val) {
+  this->threads = val;
+__isset.threads = true;
+}
 
 uint32_t BatchScanOptions::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1218,15 +1661,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->authorizations.clear();
-            uint32_t _size39;
-            ::apache::thrift::protocol::TType _etype42;
-            xfer += iprot->readSetBegin(_etype42, _size39);
-            uint32_t _i43;
-            for (_i43 = 0; _i43 < _size39; ++_i43)
+            uint32_t _size57;
+            ::apache::thrift::protocol::TType _etype60;
+            xfer += iprot->readSetBegin(_etype60, _size57);
+            uint32_t _i61;
+            for (_i61 = 0; _i61 < _size57; ++_i61)
             {
-              std::string _elem44;
-              xfer += iprot->readBinary(_elem44);
-              this->authorizations.insert(_elem44);
+              std::string _elem62;
+              xfer += iprot->readBinary(_elem62);
+              this->authorizations.insert(_elem62);
             }
             xfer += iprot->readSetEnd();
           }
@@ -1239,14 +1682,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->ranges.clear();
-            uint32_t _size45;
-            ::apache::thrift::protocol::TType _etype48;
-            xfer += iprot->readListBegin(_etype48, _size45);
-            this->ranges.resize(_size45);
-            uint32_t _i49;
-            for (_i49 = 0; _i49 < _size45; ++_i49)
+            uint32_t _size63;
+            ::apache::thrift::protocol::TType _etype66;
+            xfer += iprot->readListBegin(_etype66, _size63);
+            this->ranges.resize(_size63);
+            uint32_t _i67;
+            for (_i67 = 0; _i67 < _size63; ++_i67)
             {
-              xfer += this->ranges[_i49].read(iprot);
+              xfer += this->ranges[_i67].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -1259,14 +1702,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->columns.clear();
-            uint32_t _size50;
-            ::apache::thrift::protocol::TType _etype53;
-            xfer += iprot->readListBegin(_etype53, _size50);
-            this->columns.resize(_size50);
-            uint32_t _i54;
-            for (_i54 = 0; _i54 < _size50; ++_i54)
+            uint32_t _size68;
+            ::apache::thrift::protocol::TType _etype71;
+            xfer += iprot->readListBegin(_etype71, _size68);
+            this->columns.resize(_size68);
+            uint32_t _i72;
+            for (_i72 = 0; _i72 < _size68; ++_i72)
             {
-              xfer += this->columns[_i54].read(iprot);
+              xfer += this->columns[_i72].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -1279,14 +1722,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->iterators.clear();
-            uint32_t _size55;
-            ::apache::thrift::protocol::TType _etype58;
-            xfer += iprot->readListBegin(_etype58, _size55);
-            this->iterators.resize(_size55);
-            uint32_t _i59;
-            for (_i59 = 0; _i59 < _size55; ++_i59)
+            uint32_t _size73;
+            ::apache::thrift::protocol::TType _etype76;
+            xfer += iprot->readListBegin(_etype76, _size73);
+            this->iterators.resize(_size73);
+            uint32_t _i77;
+            for (_i77 = 0; _i77 < _size73; ++_i77)
             {
-              xfer += this->iterators[_i59].read(iprot);
+              xfer += this->iterators[_i77].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -1317,16 +1760,17 @@
 
 uint32_t BatchScanOptions::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("BatchScanOptions");
 
   if (this->__isset.authorizations) {
     xfer += oprot->writeFieldBegin("authorizations", ::apache::thrift::protocol::T_SET, 1);
     {
       xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->authorizations.size()));
-      std::set<std::string> ::const_iterator _iter60;
-      for (_iter60 = this->authorizations.begin(); _iter60 != this->authorizations.end(); ++_iter60)
+      std::set<std::string> ::const_iterator _iter78;
+      for (_iter78 = this->authorizations.begin(); _iter78 != this->authorizations.end(); ++_iter78)
       {
-        xfer += oprot->writeBinary((*_iter60));
+        xfer += oprot->writeBinary((*_iter78));
       }
       xfer += oprot->writeSetEnd();
     }
@@ -1336,10 +1780,10 @@
     xfer += oprot->writeFieldBegin("ranges", ::apache::thrift::protocol::T_LIST, 2);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->ranges.size()));
-      std::vector<Range> ::const_iterator _iter61;
-      for (_iter61 = this->ranges.begin(); _iter61 != this->ranges.end(); ++_iter61)
+      std::vector<Range> ::const_iterator _iter79;
+      for (_iter79 = this->ranges.begin(); _iter79 != this->ranges.end(); ++_iter79)
       {
-        xfer += (*_iter61).write(oprot);
+        xfer += (*_iter79).write(oprot);
       }
       xfer += oprot->writeListEnd();
     }
@@ -1349,10 +1793,10 @@
     xfer += oprot->writeFieldBegin("columns", ::apache::thrift::protocol::T_LIST, 3);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->columns.size()));
-      std::vector<ScanColumn> ::const_iterator _iter62;
-      for (_iter62 = this->columns.begin(); _iter62 != this->columns.end(); ++_iter62)
+      std::vector<ScanColumn> ::const_iterator _iter80;
+      for (_iter80 = this->columns.begin(); _iter80 != this->columns.end(); ++_iter80)
       {
-        xfer += (*_iter62).write(oprot);
+        xfer += (*_iter80).write(oprot);
       }
       xfer += oprot->writeListEnd();
     }
@@ -1362,10 +1806,10 @@
     xfer += oprot->writeFieldBegin("iterators", ::apache::thrift::protocol::T_LIST, 4);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->iterators.size()));
-      std::vector<IteratorSetting> ::const_iterator _iter63;
-      for (_iter63 = this->iterators.begin(); _iter63 != this->iterators.end(); ++_iter63)
+      std::vector<IteratorSetting> ::const_iterator _iter81;
+      for (_iter81 = this->iterators.begin(); _iter81 != this->iterators.end(); ++_iter81)
       {
-        xfer += (*_iter63).write(oprot);
+        xfer += (*_iter81).write(oprot);
       }
       xfer += oprot->writeListEnd();
     }
@@ -1391,11 +1835,50 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* KeyValueAndPeek::ascii_fingerprint = "CBBC6AB9C7EA5E5E748C13F970862FAB";
-const uint8_t KeyValueAndPeek::binary_fingerprint[16] = {0xCB,0xBC,0x6A,0xB9,0xC7,0xEA,0x5E,0x5E,0x74,0x8C,0x13,0xF9,0x70,0x86,0x2F,0xAB};
+BatchScanOptions::BatchScanOptions(const BatchScanOptions& other82) {
+  authorizations = other82.authorizations;
+  ranges = other82.ranges;
+  columns = other82.columns;
+  iterators = other82.iterators;
+  threads = other82.threads;
+  __isset = other82.__isset;
+}
+BatchScanOptions& BatchScanOptions::operator=(const BatchScanOptions& other83) {
+  authorizations = other83.authorizations;
+  ranges = other83.ranges;
+  columns = other83.columns;
+  iterators = other83.iterators;
+  threads = other83.threads;
+  __isset = other83.__isset;
+  return *this;
+}
+void BatchScanOptions::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "BatchScanOptions(";
+  out << "authorizations="; (__isset.authorizations ? (out << to_string(authorizations)) : (out << "<null>"));
+  out << ", " << "ranges="; (__isset.ranges ? (out << to_string(ranges)) : (out << "<null>"));
+  out << ", " << "columns="; (__isset.columns ? (out << to_string(columns)) : (out << "<null>"));
+  out << ", " << "iterators="; (__isset.iterators ? (out << to_string(iterators)) : (out << "<null>"));
+  out << ", " << "threads="; (__isset.threads ? (out << to_string(threads)) : (out << "<null>"));
+  out << ")";
+}
+
+
+KeyValueAndPeek::~KeyValueAndPeek() throw() {
+}
+
+
+void KeyValueAndPeek::__set_keyValue(const KeyValue& val) {
+  this->keyValue = val;
+}
+
+void KeyValueAndPeek::__set_hasNext(const bool val) {
+  this->hasNext = val;
+}
 
 uint32_t KeyValueAndPeek::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1444,6 +1927,7 @@
 
 uint32_t KeyValueAndPeek::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("KeyValueAndPeek");
 
   xfer += oprot->writeFieldBegin("keyValue", ::apache::thrift::protocol::T_STRUCT, 1);
@@ -1466,11 +1950,45 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* KeyExtent::ascii_fingerprint = "AB879940BD15B6B25691265F7384B271";
-const uint8_t KeyExtent::binary_fingerprint[16] = {0xAB,0x87,0x99,0x40,0xBD,0x15,0xB6,0xB2,0x56,0x91,0x26,0x5F,0x73,0x84,0xB2,0x71};
+KeyValueAndPeek::KeyValueAndPeek(const KeyValueAndPeek& other84) {
+  keyValue = other84.keyValue;
+  hasNext = other84.hasNext;
+  __isset = other84.__isset;
+}
+KeyValueAndPeek& KeyValueAndPeek::operator=(const KeyValueAndPeek& other85) {
+  keyValue = other85.keyValue;
+  hasNext = other85.hasNext;
+  __isset = other85.__isset;
+  return *this;
+}
+void KeyValueAndPeek::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "KeyValueAndPeek(";
+  out << "keyValue=" << to_string(keyValue);
+  out << ", " << "hasNext=" << to_string(hasNext);
+  out << ")";
+}
+
+
+KeyExtent::~KeyExtent() throw() {
+}
+
+
+void KeyExtent::__set_tableId(const std::string& val) {
+  this->tableId = val;
+}
+
+void KeyExtent::__set_endRow(const std::string& val) {
+  this->endRow = val;
+}
+
+void KeyExtent::__set_prevEndRow(const std::string& val) {
+  this->prevEndRow = val;
+}
 
 uint32_t KeyExtent::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1527,6 +2045,7 @@
 
 uint32_t KeyExtent::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("KeyExtent");
 
   xfer += oprot->writeFieldBegin("tableId", ::apache::thrift::protocol::T_STRING, 1);
@@ -1554,11 +2073,48 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* Column::ascii_fingerprint = "AB879940BD15B6B25691265F7384B271";
-const uint8_t Column::binary_fingerprint[16] = {0xAB,0x87,0x99,0x40,0xBD,0x15,0xB6,0xB2,0x56,0x91,0x26,0x5F,0x73,0x84,0xB2,0x71};
+KeyExtent::KeyExtent(const KeyExtent& other86) {
+  tableId = other86.tableId;
+  endRow = other86.endRow;
+  prevEndRow = other86.prevEndRow;
+  __isset = other86.__isset;
+}
+KeyExtent& KeyExtent::operator=(const KeyExtent& other87) {
+  tableId = other87.tableId;
+  endRow = other87.endRow;
+  prevEndRow = other87.prevEndRow;
+  __isset = other87.__isset;
+  return *this;
+}
+void KeyExtent::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "KeyExtent(";
+  out << "tableId=" << to_string(tableId);
+  out << ", " << "endRow=" << to_string(endRow);
+  out << ", " << "prevEndRow=" << to_string(prevEndRow);
+  out << ")";
+}
+
+
+Column::~Column() throw() {
+}
+
+
+void Column::__set_colFamily(const std::string& val) {
+  this->colFamily = val;
+}
+
+void Column::__set_colQualifier(const std::string& val) {
+  this->colQualifier = val;
+}
+
+void Column::__set_colVisibility(const std::string& val) {
+  this->colVisibility = val;
+}
 
 uint32_t Column::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1615,6 +2171,7 @@
 
 uint32_t Column::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("Column");
 
   xfer += oprot->writeFieldBegin("colFamily", ::apache::thrift::protocol::T_STRING, 1);
@@ -1642,11 +2199,55 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* Condition::ascii_fingerprint = "C4022914C22D89E33B1A46A7D511C58F";
-const uint8_t Condition::binary_fingerprint[16] = {0xC4,0x02,0x29,0x14,0xC2,0x2D,0x89,0xE3,0x3B,0x1A,0x46,0xA7,0xD5,0x11,0xC5,0x8F};
+Column::Column(const Column& other88) {
+  colFamily = other88.colFamily;
+  colQualifier = other88.colQualifier;
+  colVisibility = other88.colVisibility;
+  __isset = other88.__isset;
+}
+Column& Column::operator=(const Column& other89) {
+  colFamily = other89.colFamily;
+  colQualifier = other89.colQualifier;
+  colVisibility = other89.colVisibility;
+  __isset = other89.__isset;
+  return *this;
+}
+void Column::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "Column(";
+  out << "colFamily=" << to_string(colFamily);
+  out << ", " << "colQualifier=" << to_string(colQualifier);
+  out << ", " << "colVisibility=" << to_string(colVisibility);
+  out << ")";
+}
+
+
+Condition::~Condition() throw() {
+}
+
+
+void Condition::__set_column(const Column& val) {
+  this->column = val;
+}
+
+void Condition::__set_timestamp(const int64_t val) {
+  this->timestamp = val;
+__isset.timestamp = true;
+}
+
+void Condition::__set_value(const std::string& val) {
+  this->value = val;
+__isset.value = true;
+}
+
+void Condition::__set_iterators(const std::vector<IteratorSetting> & val) {
+  this->iterators = val;
+__isset.iterators = true;
+}
 
 uint32_t Condition::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1693,14 +2294,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->iterators.clear();
-            uint32_t _size64;
-            ::apache::thrift::protocol::TType _etype67;
-            xfer += iprot->readListBegin(_etype67, _size64);
-            this->iterators.resize(_size64);
-            uint32_t _i68;
-            for (_i68 = 0; _i68 < _size64; ++_i68)
+            uint32_t _size90;
+            ::apache::thrift::protocol::TType _etype93;
+            xfer += iprot->readListBegin(_etype93, _size90);
+            this->iterators.resize(_size90);
+            uint32_t _i94;
+            for (_i94 = 0; _i94 < _size90; ++_i94)
             {
-              xfer += this->iterators[_i68].read(iprot);
+              xfer += this->iterators[_i94].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -1723,6 +2324,7 @@
 
 uint32_t Condition::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("Condition");
 
   xfer += oprot->writeFieldBegin("column", ::apache::thrift::protocol::T_STRUCT, 1);
@@ -1743,10 +2345,10 @@
     xfer += oprot->writeFieldBegin("iterators", ::apache::thrift::protocol::T_LIST, 4);
     {
       xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->iterators.size()));
-      std::vector<IteratorSetting> ::const_iterator _iter69;
-      for (_iter69 = this->iterators.begin(); _iter69 != this->iterators.end(); ++_iter69)
+      std::vector<IteratorSetting> ::const_iterator _iter95;
+      for (_iter95 = this->iterators.begin(); _iter95 != this->iterators.end(); ++_iter95)
       {
-        xfer += (*_iter69).write(oprot);
+        xfer += (*_iter95).write(oprot);
       }
       xfer += oprot->writeListEnd();
     }
@@ -1766,11 +2368,47 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* ConditionalUpdates::ascii_fingerprint = "1C1808872D1A8E04F114974ADD77F356";
-const uint8_t ConditionalUpdates::binary_fingerprint[16] = {0x1C,0x18,0x08,0x87,0x2D,0x1A,0x8E,0x04,0xF1,0x14,0x97,0x4A,0xDD,0x77,0xF3,0x56};
+Condition::Condition(const Condition& other96) {
+  column = other96.column;
+  timestamp = other96.timestamp;
+  value = other96.value;
+  iterators = other96.iterators;
+  __isset = other96.__isset;
+}
+Condition& Condition::operator=(const Condition& other97) {
+  column = other97.column;
+  timestamp = other97.timestamp;
+  value = other97.value;
+  iterators = other97.iterators;
+  __isset = other97.__isset;
+  return *this;
+}
+void Condition::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "Condition(";
+  out << "column=" << to_string(column);
+  out << ", " << "timestamp="; (__isset.timestamp ? (out << to_string(timestamp)) : (out << "<null>"));
+  out << ", " << "value="; (__isset.value ? (out << to_string(value)) : (out << "<null>"));
+  out << ", " << "iterators="; (__isset.iterators ? (out << to_string(iterators)) : (out << "<null>"));
+  out << ")";
+}
+
+
+ConditionalUpdates::~ConditionalUpdates() throw() {
+}
+
+
+void ConditionalUpdates::__set_conditions(const std::vector<Condition> & val) {
+  this->conditions = val;
+}
+
+void ConditionalUpdates::__set_updates(const std::vector<ColumnUpdate> & val) {
+  this->updates = val;
+}
 
 uint32_t ConditionalUpdates::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1793,14 +2431,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->conditions.clear();
-            uint32_t _size70;
-            ::apache::thrift::protocol::TType _etype73;
-            xfer += iprot->readListBegin(_etype73, _size70);
-            this->conditions.resize(_size70);
-            uint32_t _i74;
-            for (_i74 = 0; _i74 < _size70; ++_i74)
+            uint32_t _size98;
+            ::apache::thrift::protocol::TType _etype101;
+            xfer += iprot->readListBegin(_etype101, _size98);
+            this->conditions.resize(_size98);
+            uint32_t _i102;
+            for (_i102 = 0; _i102 < _size98; ++_i102)
             {
-              xfer += this->conditions[_i74].read(iprot);
+              xfer += this->conditions[_i102].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -1813,14 +2451,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->updates.clear();
-            uint32_t _size75;
-            ::apache::thrift::protocol::TType _etype78;
-            xfer += iprot->readListBegin(_etype78, _size75);
-            this->updates.resize(_size75);
-            uint32_t _i79;
-            for (_i79 = 0; _i79 < _size75; ++_i79)
+            uint32_t _size103;
+            ::apache::thrift::protocol::TType _etype106;
+            xfer += iprot->readListBegin(_etype106, _size103);
+            this->updates.resize(_size103);
+            uint32_t _i107;
+            for (_i107 = 0; _i107 < _size103; ++_i107)
             {
-              xfer += this->updates[_i79].read(iprot);
+              xfer += this->updates[_i107].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -1843,15 +2481,16 @@
 
 uint32_t ConditionalUpdates::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("ConditionalUpdates");
 
   xfer += oprot->writeFieldBegin("conditions", ::apache::thrift::protocol::T_LIST, 2);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->conditions.size()));
-    std::vector<Condition> ::const_iterator _iter80;
-    for (_iter80 = this->conditions.begin(); _iter80 != this->conditions.end(); ++_iter80)
+    std::vector<Condition> ::const_iterator _iter108;
+    for (_iter108 = this->conditions.begin(); _iter108 != this->conditions.end(); ++_iter108)
     {
-      xfer += (*_iter80).write(oprot);
+      xfer += (*_iter108).write(oprot);
     }
     xfer += oprot->writeListEnd();
   }
@@ -1860,10 +2499,10 @@
   xfer += oprot->writeFieldBegin("updates", ::apache::thrift::protocol::T_LIST, 3);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->updates.size()));
-    std::vector<ColumnUpdate> ::const_iterator _iter81;
-    for (_iter81 = this->updates.begin(); _iter81 != this->updates.end(); ++_iter81)
+    std::vector<ColumnUpdate> ::const_iterator _iter109;
+    for (_iter109 = this->updates.begin(); _iter109 != this->updates.end(); ++_iter109)
     {
-      xfer += (*_iter81).write(oprot);
+      xfer += (*_iter109).write(oprot);
     }
     xfer += oprot->writeListEnd();
   }
@@ -1881,11 +2520,58 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* ConditionalWriterOptions::ascii_fingerprint = "C345C04E84A351638B6EACB741BD600E";
-const uint8_t ConditionalWriterOptions::binary_fingerprint[16] = {0xC3,0x45,0xC0,0x4E,0x84,0xA3,0x51,0x63,0x8B,0x6E,0xAC,0xB7,0x41,0xBD,0x60,0x0E};
+ConditionalUpdates::ConditionalUpdates(const ConditionalUpdates& other110) {
+  conditions = other110.conditions;
+  updates = other110.updates;
+  __isset = other110.__isset;
+}
+ConditionalUpdates& ConditionalUpdates::operator=(const ConditionalUpdates& other111) {
+  conditions = other111.conditions;
+  updates = other111.updates;
+  __isset = other111.__isset;
+  return *this;
+}
+void ConditionalUpdates::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "ConditionalUpdates(";
+  out << "conditions=" << to_string(conditions);
+  out << ", " << "updates=" << to_string(updates);
+  out << ")";
+}
+
+
+ConditionalWriterOptions::~ConditionalWriterOptions() throw() {
+}
+
+
+void ConditionalWriterOptions::__set_maxMemory(const int64_t val) {
+  this->maxMemory = val;
+__isset.maxMemory = true;
+}
+
+void ConditionalWriterOptions::__set_timeoutMs(const int64_t val) {
+  this->timeoutMs = val;
+__isset.timeoutMs = true;
+}
+
+void ConditionalWriterOptions::__set_threads(const int32_t val) {
+  this->threads = val;
+__isset.threads = true;
+}
+
+void ConditionalWriterOptions::__set_authorizations(const std::set<std::string> & val) {
+  this->authorizations = val;
+__isset.authorizations = true;
+}
+
+void ConditionalWriterOptions::__set_durability(const Durability::type val) {
+  this->durability = val;
+__isset.durability = true;
+}
 
 uint32_t ConditionalWriterOptions::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -1932,15 +2618,15 @@
         if (ftype == ::apache::thrift::protocol::T_SET) {
           {
             this->authorizations.clear();
-            uint32_t _size82;
-            ::apache::thrift::protocol::TType _etype85;
-            xfer += iprot->readSetBegin(_etype85, _size82);
-            uint32_t _i86;
-            for (_i86 = 0; _i86 < _size82; ++_i86)
+            uint32_t _size112;
+            ::apache::thrift::protocol::TType _etype115;
+            xfer += iprot->readSetBegin(_etype115, _size112);
+            uint32_t _i116;
+            for (_i116 = 0; _i116 < _size112; ++_i116)
             {
-              std::string _elem87;
-              xfer += iprot->readBinary(_elem87);
-              this->authorizations.insert(_elem87);
+              std::string _elem117;
+              xfer += iprot->readBinary(_elem117);
+              this->authorizations.insert(_elem117);
             }
             xfer += iprot->readSetEnd();
           }
@@ -1951,9 +2637,9 @@
         break;
       case 5:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast88;
-          xfer += iprot->readI32(ecast88);
-          this->durability = (Durability::type)ecast88;
+          int32_t ecast118;
+          xfer += iprot->readI32(ecast118);
+          this->durability = (Durability::type)ecast118;
           this->__isset.durability = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -1973,6 +2659,7 @@
 
 uint32_t ConditionalWriterOptions::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("ConditionalWriterOptions");
 
   if (this->__isset.maxMemory) {
@@ -1994,10 +2681,10 @@
     xfer += oprot->writeFieldBegin("authorizations", ::apache::thrift::protocol::T_SET, 4);
     {
       xfer += oprot->writeSetBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->authorizations.size()));
-      std::set<std::string> ::const_iterator _iter89;
-      for (_iter89 = this->authorizations.begin(); _iter89 != this->authorizations.end(); ++_iter89)
+      std::set<std::string> ::const_iterator _iter119;
+      for (_iter119 = this->authorizations.begin(); _iter119 != this->authorizations.end(); ++_iter119)
       {
-        xfer += oprot->writeBinary((*_iter89));
+        xfer += oprot->writeBinary((*_iter119));
       }
       xfer += oprot->writeSetEnd();
     }
@@ -2023,11 +2710,86 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* ActiveScan::ascii_fingerprint = "1B97541CB4E900A054266BBBEE61D004";
-const uint8_t ActiveScan::binary_fingerprint[16] = {0x1B,0x97,0x54,0x1C,0xB4,0xE9,0x00,0xA0,0x54,0x26,0x6B,0xBB,0xEE,0x61,0xD0,0x04};
+ConditionalWriterOptions::ConditionalWriterOptions(const ConditionalWriterOptions& other120) {
+  maxMemory = other120.maxMemory;
+  timeoutMs = other120.timeoutMs;
+  threads = other120.threads;
+  authorizations = other120.authorizations;
+  durability = other120.durability;
+  __isset = other120.__isset;
+}
+ConditionalWriterOptions& ConditionalWriterOptions::operator=(const ConditionalWriterOptions& other121) {
+  maxMemory = other121.maxMemory;
+  timeoutMs = other121.timeoutMs;
+  threads = other121.threads;
+  authorizations = other121.authorizations;
+  durability = other121.durability;
+  __isset = other121.__isset;
+  return *this;
+}
+void ConditionalWriterOptions::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "ConditionalWriterOptions(";
+  out << "maxMemory="; (__isset.maxMemory ? (out << to_string(maxMemory)) : (out << "<null>"));
+  out << ", " << "timeoutMs="; (__isset.timeoutMs ? (out << to_string(timeoutMs)) : (out << "<null>"));
+  out << ", " << "threads="; (__isset.threads ? (out << to_string(threads)) : (out << "<null>"));
+  out << ", " << "authorizations="; (__isset.authorizations ? (out << to_string(authorizations)) : (out << "<null>"));
+  out << ", " << "durability="; (__isset.durability ? (out << to_string(durability)) : (out << "<null>"));
+  out << ")";
+}
+
+
+ActiveScan::~ActiveScan() throw() {
+}
+
+
+void ActiveScan::__set_client(const std::string& val) {
+  this->client = val;
+}
+
+void ActiveScan::__set_user(const std::string& val) {
+  this->user = val;
+}
+
+void ActiveScan::__set_table(const std::string& val) {
+  this->table = val;
+}
+
+void ActiveScan::__set_age(const int64_t val) {
+  this->age = val;
+}
+
+void ActiveScan::__set_idleTime(const int64_t val) {
+  this->idleTime = val;
+}
+
+void ActiveScan::__set_type(const ScanType::type val) {
+  this->type = val;
+}
+
+void ActiveScan::__set_state(const ScanState::type val) {
+  this->state = val;
+}
+
+void ActiveScan::__set_extent(const KeyExtent& val) {
+  this->extent = val;
+}
+
+void ActiveScan::__set_columns(const std::vector<Column> & val) {
+  this->columns = val;
+}
+
+void ActiveScan::__set_iterators(const std::vector<IteratorSetting> & val) {
+  this->iterators = val;
+}
+
+void ActiveScan::__set_authorizations(const std::vector<std::string> & val) {
+  this->authorizations = val;
+}
 
 uint32_t ActiveScan::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2088,9 +2850,9 @@
         break;
       case 6:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast90;
-          xfer += iprot->readI32(ecast90);
-          this->type = (ScanType::type)ecast90;
+          int32_t ecast122;
+          xfer += iprot->readI32(ecast122);
+          this->type = (ScanType::type)ecast122;
           this->__isset.type = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -2098,9 +2860,9 @@
         break;
       case 7:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast91;
-          xfer += iprot->readI32(ecast91);
-          this->state = (ScanState::type)ecast91;
+          int32_t ecast123;
+          xfer += iprot->readI32(ecast123);
+          this->state = (ScanState::type)ecast123;
           this->__isset.state = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -2118,14 +2880,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->columns.clear();
-            uint32_t _size92;
-            ::apache::thrift::protocol::TType _etype95;
-            xfer += iprot->readListBegin(_etype95, _size92);
-            this->columns.resize(_size92);
-            uint32_t _i96;
-            for (_i96 = 0; _i96 < _size92; ++_i96)
+            uint32_t _size124;
+            ::apache::thrift::protocol::TType _etype127;
+            xfer += iprot->readListBegin(_etype127, _size124);
+            this->columns.resize(_size124);
+            uint32_t _i128;
+            for (_i128 = 0; _i128 < _size124; ++_i128)
             {
-              xfer += this->columns[_i96].read(iprot);
+              xfer += this->columns[_i128].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -2138,14 +2900,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->iterators.clear();
-            uint32_t _size97;
-            ::apache::thrift::protocol::TType _etype100;
-            xfer += iprot->readListBegin(_etype100, _size97);
-            this->iterators.resize(_size97);
-            uint32_t _i101;
-            for (_i101 = 0; _i101 < _size97; ++_i101)
+            uint32_t _size129;
+            ::apache::thrift::protocol::TType _etype132;
+            xfer += iprot->readListBegin(_etype132, _size129);
+            this->iterators.resize(_size129);
+            uint32_t _i133;
+            for (_i133 = 0; _i133 < _size129; ++_i133)
             {
-              xfer += this->iterators[_i101].read(iprot);
+              xfer += this->iterators[_i133].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -2158,14 +2920,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->authorizations.clear();
-            uint32_t _size102;
-            ::apache::thrift::protocol::TType _etype105;
-            xfer += iprot->readListBegin(_etype105, _size102);
-            this->authorizations.resize(_size102);
-            uint32_t _i106;
-            for (_i106 = 0; _i106 < _size102; ++_i106)
+            uint32_t _size134;
+            ::apache::thrift::protocol::TType _etype137;
+            xfer += iprot->readListBegin(_etype137, _size134);
+            this->authorizations.resize(_size134);
+            uint32_t _i138;
+            for (_i138 = 0; _i138 < _size134; ++_i138)
             {
-              xfer += iprot->readBinary(this->authorizations[_i106]);
+              xfer += iprot->readBinary(this->authorizations[_i138]);
             }
             xfer += iprot->readListEnd();
           }
@@ -2188,6 +2950,7 @@
 
 uint32_t ActiveScan::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("ActiveScan");
 
   xfer += oprot->writeFieldBegin("client", ::apache::thrift::protocol::T_STRING, 1);
@@ -2225,10 +2988,10 @@
   xfer += oprot->writeFieldBegin("columns", ::apache::thrift::protocol::T_LIST, 9);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->columns.size()));
-    std::vector<Column> ::const_iterator _iter107;
-    for (_iter107 = this->columns.begin(); _iter107 != this->columns.end(); ++_iter107)
+    std::vector<Column> ::const_iterator _iter139;
+    for (_iter139 = this->columns.begin(); _iter139 != this->columns.end(); ++_iter139)
     {
-      xfer += (*_iter107).write(oprot);
+      xfer += (*_iter139).write(oprot);
     }
     xfer += oprot->writeListEnd();
   }
@@ -2237,10 +3000,10 @@
   xfer += oprot->writeFieldBegin("iterators", ::apache::thrift::protocol::T_LIST, 10);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->iterators.size()));
-    std::vector<IteratorSetting> ::const_iterator _iter108;
-    for (_iter108 = this->iterators.begin(); _iter108 != this->iterators.end(); ++_iter108)
+    std::vector<IteratorSetting> ::const_iterator _iter140;
+    for (_iter140 = this->iterators.begin(); _iter140 != this->iterators.end(); ++_iter140)
     {
-      xfer += (*_iter108).write(oprot);
+      xfer += (*_iter140).write(oprot);
     }
     xfer += oprot->writeListEnd();
   }
@@ -2249,10 +3012,10 @@
   xfer += oprot->writeFieldBegin("authorizations", ::apache::thrift::protocol::T_LIST, 11);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->authorizations.size()));
-    std::vector<std::string> ::const_iterator _iter109;
-    for (_iter109 = this->authorizations.begin(); _iter109 != this->authorizations.end(); ++_iter109)
+    std::vector<std::string> ::const_iterator _iter141;
+    for (_iter141 = this->authorizations.begin(); _iter141 != this->authorizations.end(); ++_iter141)
     {
-      xfer += oprot->writeBinary((*_iter109));
+      xfer += oprot->writeBinary((*_iter141));
     }
     xfer += oprot->writeListEnd();
   }
@@ -2279,11 +3042,100 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* ActiveCompaction::ascii_fingerprint = "2BB155CC901109464666B6C7E6A8C1A6";
-const uint8_t ActiveCompaction::binary_fingerprint[16] = {0x2B,0xB1,0x55,0xCC,0x90,0x11,0x09,0x46,0x46,0x66,0xB6,0xC7,0xE6,0xA8,0xC1,0xA6};
+ActiveScan::ActiveScan(const ActiveScan& other142) {
+  client = other142.client;
+  user = other142.user;
+  table = other142.table;
+  age = other142.age;
+  idleTime = other142.idleTime;
+  type = other142.type;
+  state = other142.state;
+  extent = other142.extent;
+  columns = other142.columns;
+  iterators = other142.iterators;
+  authorizations = other142.authorizations;
+  __isset = other142.__isset;
+}
+ActiveScan& ActiveScan::operator=(const ActiveScan& other143) {
+  client = other143.client;
+  user = other143.user;
+  table = other143.table;
+  age = other143.age;
+  idleTime = other143.idleTime;
+  type = other143.type;
+  state = other143.state;
+  extent = other143.extent;
+  columns = other143.columns;
+  iterators = other143.iterators;
+  authorizations = other143.authorizations;
+  __isset = other143.__isset;
+  return *this;
+}
+void ActiveScan::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "ActiveScan(";
+  out << "client=" << to_string(client);
+  out << ", " << "user=" << to_string(user);
+  out << ", " << "table=" << to_string(table);
+  out << ", " << "age=" << to_string(age);
+  out << ", " << "idleTime=" << to_string(idleTime);
+  out << ", " << "type=" << to_string(type);
+  out << ", " << "state=" << to_string(state);
+  out << ", " << "extent=" << to_string(extent);
+  out << ", " << "columns=" << to_string(columns);
+  out << ", " << "iterators=" << to_string(iterators);
+  out << ", " << "authorizations=" << to_string(authorizations);
+  out << ")";
+}
+
+
+ActiveCompaction::~ActiveCompaction() throw() {
+}
+
+
+void ActiveCompaction::__set_extent(const KeyExtent& val) {
+  this->extent = val;
+}
+
+void ActiveCompaction::__set_age(const int64_t val) {
+  this->age = val;
+}
+
+void ActiveCompaction::__set_inputFiles(const std::vector<std::string> & val) {
+  this->inputFiles = val;
+}
+
+void ActiveCompaction::__set_outputFile(const std::string& val) {
+  this->outputFile = val;
+}
+
+void ActiveCompaction::__set_type(const CompactionType::type val) {
+  this->type = val;
+}
+
+void ActiveCompaction::__set_reason(const CompactionReason::type val) {
+  this->reason = val;
+}
+
+void ActiveCompaction::__set_localityGroup(const std::string& val) {
+  this->localityGroup = val;
+}
+
+void ActiveCompaction::__set_entriesRead(const int64_t val) {
+  this->entriesRead = val;
+}
+
+void ActiveCompaction::__set_entriesWritten(const int64_t val) {
+  this->entriesWritten = val;
+}
+
+void ActiveCompaction::__set_iterators(const std::vector<IteratorSetting> & val) {
+  this->iterators = val;
+}
 
 uint32_t ActiveCompaction::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2322,14 +3174,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->inputFiles.clear();
-            uint32_t _size110;
-            ::apache::thrift::protocol::TType _etype113;
-            xfer += iprot->readListBegin(_etype113, _size110);
-            this->inputFiles.resize(_size110);
-            uint32_t _i114;
-            for (_i114 = 0; _i114 < _size110; ++_i114)
+            uint32_t _size144;
+            ::apache::thrift::protocol::TType _etype147;
+            xfer += iprot->readListBegin(_etype147, _size144);
+            this->inputFiles.resize(_size144);
+            uint32_t _i148;
+            for (_i148 = 0; _i148 < _size144; ++_i148)
             {
-              xfer += iprot->readString(this->inputFiles[_i114]);
+              xfer += iprot->readString(this->inputFiles[_i148]);
             }
             xfer += iprot->readListEnd();
           }
@@ -2348,9 +3200,9 @@
         break;
       case 5:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast115;
-          xfer += iprot->readI32(ecast115);
-          this->type = (CompactionType::type)ecast115;
+          int32_t ecast149;
+          xfer += iprot->readI32(ecast149);
+          this->type = (CompactionType::type)ecast149;
           this->__isset.type = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -2358,9 +3210,9 @@
         break;
       case 6:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast116;
-          xfer += iprot->readI32(ecast116);
-          this->reason = (CompactionReason::type)ecast116;
+          int32_t ecast150;
+          xfer += iprot->readI32(ecast150);
+          this->reason = (CompactionReason::type)ecast150;
           this->__isset.reason = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -2394,14 +3246,14 @@
         if (ftype == ::apache::thrift::protocol::T_LIST) {
           {
             this->iterators.clear();
-            uint32_t _size117;
-            ::apache::thrift::protocol::TType _etype120;
-            xfer += iprot->readListBegin(_etype120, _size117);
-            this->iterators.resize(_size117);
-            uint32_t _i121;
-            for (_i121 = 0; _i121 < _size117; ++_i121)
+            uint32_t _size151;
+            ::apache::thrift::protocol::TType _etype154;
+            xfer += iprot->readListBegin(_etype154, _size151);
+            this->iterators.resize(_size151);
+            uint32_t _i155;
+            for (_i155 = 0; _i155 < _size151; ++_i155)
             {
-              xfer += this->iterators[_i121].read(iprot);
+              xfer += this->iterators[_i155].read(iprot);
             }
             xfer += iprot->readListEnd();
           }
@@ -2424,6 +3276,7 @@
 
 uint32_t ActiveCompaction::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("ActiveCompaction");
 
   xfer += oprot->writeFieldBegin("extent", ::apache::thrift::protocol::T_STRUCT, 1);
@@ -2437,10 +3290,10 @@
   xfer += oprot->writeFieldBegin("inputFiles", ::apache::thrift::protocol::T_LIST, 3);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->inputFiles.size()));
-    std::vector<std::string> ::const_iterator _iter122;
-    for (_iter122 = this->inputFiles.begin(); _iter122 != this->inputFiles.end(); ++_iter122)
+    std::vector<std::string> ::const_iterator _iter156;
+    for (_iter156 = this->inputFiles.begin(); _iter156 != this->inputFiles.end(); ++_iter156)
     {
-      xfer += oprot->writeString((*_iter122));
+      xfer += oprot->writeString((*_iter156));
     }
     xfer += oprot->writeListEnd();
   }
@@ -2473,10 +3326,10 @@
   xfer += oprot->writeFieldBegin("iterators", ::apache::thrift::protocol::T_LIST, 10);
   {
     xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->iterators.size()));
-    std::vector<IteratorSetting> ::const_iterator _iter123;
-    for (_iter123 = this->iterators.begin(); _iter123 != this->iterators.end(); ++_iter123)
+    std::vector<IteratorSetting> ::const_iterator _iter157;
+    for (_iter157 = this->iterators.begin(); _iter157 != this->iterators.end(); ++_iter157)
     {
-      xfer += (*_iter123).write(oprot);
+      xfer += (*_iter157).write(oprot);
     }
     xfer += oprot->writeListEnd();
   }
@@ -2502,11 +3355,78 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* WriterOptions::ascii_fingerprint = "6640C55D2C0D4C8C2E7589456EA0C61A";
-const uint8_t WriterOptions::binary_fingerprint[16] = {0x66,0x40,0xC5,0x5D,0x2C,0x0D,0x4C,0x8C,0x2E,0x75,0x89,0x45,0x6E,0xA0,0xC6,0x1A};
+ActiveCompaction::ActiveCompaction(const ActiveCompaction& other158) {
+  extent = other158.extent;
+  age = other158.age;
+  inputFiles = other158.inputFiles;
+  outputFile = other158.outputFile;
+  type = other158.type;
+  reason = other158.reason;
+  localityGroup = other158.localityGroup;
+  entriesRead = other158.entriesRead;
+  entriesWritten = other158.entriesWritten;
+  iterators = other158.iterators;
+  __isset = other158.__isset;
+}
+ActiveCompaction& ActiveCompaction::operator=(const ActiveCompaction& other159) {
+  extent = other159.extent;
+  age = other159.age;
+  inputFiles = other159.inputFiles;
+  outputFile = other159.outputFile;
+  type = other159.type;
+  reason = other159.reason;
+  localityGroup = other159.localityGroup;
+  entriesRead = other159.entriesRead;
+  entriesWritten = other159.entriesWritten;
+  iterators = other159.iterators;
+  __isset = other159.__isset;
+  return *this;
+}
+void ActiveCompaction::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "ActiveCompaction(";
+  out << "extent=" << to_string(extent);
+  out << ", " << "age=" << to_string(age);
+  out << ", " << "inputFiles=" << to_string(inputFiles);
+  out << ", " << "outputFile=" << to_string(outputFile);
+  out << ", " << "type=" << to_string(type);
+  out << ", " << "reason=" << to_string(reason);
+  out << ", " << "localityGroup=" << to_string(localityGroup);
+  out << ", " << "entriesRead=" << to_string(entriesRead);
+  out << ", " << "entriesWritten=" << to_string(entriesWritten);
+  out << ", " << "iterators=" << to_string(iterators);
+  out << ")";
+}
+
+
+WriterOptions::~WriterOptions() throw() {
+}
+
+
+void WriterOptions::__set_maxMemory(const int64_t val) {
+  this->maxMemory = val;
+}
+
+void WriterOptions::__set_latencyMs(const int64_t val) {
+  this->latencyMs = val;
+}
+
+void WriterOptions::__set_timeoutMs(const int64_t val) {
+  this->timeoutMs = val;
+}
+
+void WriterOptions::__set_threads(const int32_t val) {
+  this->threads = val;
+}
+
+void WriterOptions::__set_durability(const Durability::type val) {
+  this->durability = val;
+__isset.durability = true;
+}
 
 uint32_t WriterOptions::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2559,9 +3479,9 @@
         break;
       case 5:
         if (ftype == ::apache::thrift::protocol::T_I32) {
-          int32_t ecast124;
-          xfer += iprot->readI32(ecast124);
-          this->durability = (Durability::type)ecast124;
+          int32_t ecast160;
+          xfer += iprot->readI32(ecast160);
+          this->durability = (Durability::type)ecast160;
           this->__isset.durability = true;
         } else {
           xfer += iprot->skip(ftype);
@@ -2581,6 +3501,7 @@
 
 uint32_t WriterOptions::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("WriterOptions");
 
   xfer += oprot->writeFieldBegin("maxMemory", ::apache::thrift::protocol::T_I64, 1);
@@ -2619,11 +3540,50 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* CompactionStrategyConfig::ascii_fingerprint = "F7C641917C22B35AE581CCD54910B00D";
-const uint8_t CompactionStrategyConfig::binary_fingerprint[16] = {0xF7,0xC6,0x41,0x91,0x7C,0x22,0xB3,0x5A,0xE5,0x81,0xCC,0xD5,0x49,0x10,0xB0,0x0D};
+WriterOptions::WriterOptions(const WriterOptions& other161) {
+  maxMemory = other161.maxMemory;
+  latencyMs = other161.latencyMs;
+  timeoutMs = other161.timeoutMs;
+  threads = other161.threads;
+  durability = other161.durability;
+  __isset = other161.__isset;
+}
+WriterOptions& WriterOptions::operator=(const WriterOptions& other162) {
+  maxMemory = other162.maxMemory;
+  latencyMs = other162.latencyMs;
+  timeoutMs = other162.timeoutMs;
+  threads = other162.threads;
+  durability = other162.durability;
+  __isset = other162.__isset;
+  return *this;
+}
+void WriterOptions::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "WriterOptions(";
+  out << "maxMemory=" << to_string(maxMemory);
+  out << ", " << "latencyMs=" << to_string(latencyMs);
+  out << ", " << "timeoutMs=" << to_string(timeoutMs);
+  out << ", " << "threads=" << to_string(threads);
+  out << ", " << "durability="; (__isset.durability ? (out << to_string(durability)) : (out << "<null>"));
+  out << ")";
+}
+
+
+CompactionStrategyConfig::~CompactionStrategyConfig() throw() {
+}
+
+
+void CompactionStrategyConfig::__set_className(const std::string& val) {
+  this->className = val;
+}
+
+void CompactionStrategyConfig::__set_options(const std::map<std::string, std::string> & val) {
+  this->options = val;
+}
 
 uint32_t CompactionStrategyConfig::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2654,17 +3614,17 @@
         if (ftype == ::apache::thrift::protocol::T_MAP) {
           {
             this->options.clear();
-            uint32_t _size125;
-            ::apache::thrift::protocol::TType _ktype126;
-            ::apache::thrift::protocol::TType _vtype127;
-            xfer += iprot->readMapBegin(_ktype126, _vtype127, _size125);
-            uint32_t _i129;
-            for (_i129 = 0; _i129 < _size125; ++_i129)
+            uint32_t _size163;
+            ::apache::thrift::protocol::TType _ktype164;
+            ::apache::thrift::protocol::TType _vtype165;
+            xfer += iprot->readMapBegin(_ktype164, _vtype165, _size163);
+            uint32_t _i167;
+            for (_i167 = 0; _i167 < _size163; ++_i167)
             {
-              std::string _key130;
-              xfer += iprot->readString(_key130);
-              std::string& _val131 = this->options[_key130];
-              xfer += iprot->readString(_val131);
+              std::string _key168;
+              xfer += iprot->readString(_key168);
+              std::string& _val169 = this->options[_key168];
+              xfer += iprot->readString(_val169);
             }
             xfer += iprot->readMapEnd();
           }
@@ -2687,6 +3647,7 @@
 
 uint32_t CompactionStrategyConfig::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("CompactionStrategyConfig");
 
   xfer += oprot->writeFieldBegin("className", ::apache::thrift::protocol::T_STRING, 1);
@@ -2696,11 +3657,11 @@
   xfer += oprot->writeFieldBegin("options", ::apache::thrift::protocol::T_MAP, 2);
   {
     xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->options.size()));
-    std::map<std::string, std::string> ::const_iterator _iter132;
-    for (_iter132 = this->options.begin(); _iter132 != this->options.end(); ++_iter132)
+    std::map<std::string, std::string> ::const_iterator _iter170;
+    for (_iter170 = this->options.begin(); _iter170 != this->options.end(); ++_iter170)
     {
-      xfer += oprot->writeString(_iter132->first);
-      xfer += oprot->writeString(_iter132->second);
+      xfer += oprot->writeString(_iter170->first);
+      xfer += oprot->writeString(_iter170->second);
     }
     xfer += oprot->writeMapEnd();
   }
@@ -2718,11 +3679,37 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* UnknownScanner::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1";
-const uint8_t UnknownScanner::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
+CompactionStrategyConfig::CompactionStrategyConfig(const CompactionStrategyConfig& other171) {
+  className = other171.className;
+  options = other171.options;
+  __isset = other171.__isset;
+}
+CompactionStrategyConfig& CompactionStrategyConfig::operator=(const CompactionStrategyConfig& other172) {
+  className = other172.className;
+  options = other172.options;
+  __isset = other172.__isset;
+  return *this;
+}
+void CompactionStrategyConfig::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "CompactionStrategyConfig(";
+  out << "className=" << to_string(className);
+  out << ", " << "options=" << to_string(options);
+  out << ")";
+}
+
+
+UnknownScanner::~UnknownScanner() throw() {
+}
+
+
+void UnknownScanner::__set_msg(const std::string& val) {
+  this->msg = val;
+}
 
 uint32_t UnknownScanner::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2763,6 +3750,7 @@
 
 uint32_t UnknownScanner::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("UnknownScanner");
 
   xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
@@ -2780,11 +3768,45 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* UnknownWriter::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1";
-const uint8_t UnknownWriter::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
+UnknownScanner::UnknownScanner(const UnknownScanner& other173) : TException() {
+  msg = other173.msg;
+  __isset = other173.__isset;
+}
+UnknownScanner& UnknownScanner::operator=(const UnknownScanner& other174) {
+  msg = other174.msg;
+  __isset = other174.__isset;
+  return *this;
+}
+void UnknownScanner::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "UnknownScanner(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* UnknownScanner::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: UnknownScanner";
+  }
+}
+
+
+UnknownWriter::~UnknownWriter() throw() {
+}
+
+
+void UnknownWriter::__set_msg(const std::string& val) {
+  this->msg = val;
+}
 
 uint32_t UnknownWriter::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2825,6 +3847,7 @@
 
 uint32_t UnknownWriter::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("UnknownWriter");
 
   xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
@@ -2842,11 +3865,45 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* NoMoreEntriesException::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1";
-const uint8_t NoMoreEntriesException::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
+UnknownWriter::UnknownWriter(const UnknownWriter& other175) : TException() {
+  msg = other175.msg;
+  __isset = other175.__isset;
+}
+UnknownWriter& UnknownWriter::operator=(const UnknownWriter& other176) {
+  msg = other176.msg;
+  __isset = other176.__isset;
+  return *this;
+}
+void UnknownWriter::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "UnknownWriter(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* UnknownWriter::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: UnknownWriter";
+  }
+}
+
+
+NoMoreEntriesException::~NoMoreEntriesException() throw() {
+}
+
+
+void NoMoreEntriesException::__set_msg(const std::string& val) {
+  this->msg = val;
+}
 
 uint32_t NoMoreEntriesException::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2887,6 +3944,7 @@
 
 uint32_t NoMoreEntriesException::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("NoMoreEntriesException");
 
   xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
@@ -2904,11 +3962,45 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* AccumuloException::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1";
-const uint8_t AccumuloException::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
+NoMoreEntriesException::NoMoreEntriesException(const NoMoreEntriesException& other177) : TException() {
+  msg = other177.msg;
+  __isset = other177.__isset;
+}
+NoMoreEntriesException& NoMoreEntriesException::operator=(const NoMoreEntriesException& other178) {
+  msg = other178.msg;
+  __isset = other178.__isset;
+  return *this;
+}
+void NoMoreEntriesException::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "NoMoreEntriesException(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* NoMoreEntriesException::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: NoMoreEntriesException";
+  }
+}
+
+
+AccumuloException::~AccumuloException() throw() {
+}
+
+
+void AccumuloException::__set_msg(const std::string& val) {
+  this->msg = val;
+}
 
 uint32_t AccumuloException::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -2949,6 +4041,7 @@
 
 uint32_t AccumuloException::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloException");
 
   xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
@@ -2966,11 +4059,45 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* AccumuloSecurityException::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1";
-const uint8_t AccumuloSecurityException::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
+AccumuloException::AccumuloException(const AccumuloException& other179) : TException() {
+  msg = other179.msg;
+  __isset = other179.__isset;
+}
+AccumuloException& AccumuloException::operator=(const AccumuloException& other180) {
+  msg = other180.msg;
+  __isset = other180.__isset;
+  return *this;
+}
+void AccumuloException::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "AccumuloException(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* AccumuloException::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: AccumuloException";
+  }
+}
+
+
+AccumuloSecurityException::~AccumuloSecurityException() throw() {
+}
+
+
+void AccumuloSecurityException::__set_msg(const std::string& val) {
+  this->msg = val;
+}
 
 uint32_t AccumuloSecurityException::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3011,6 +4138,7 @@
 
 uint32_t AccumuloSecurityException::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("AccumuloSecurityException");
 
   xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
@@ -3028,11 +4156,45 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* TableNotFoundException::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1";
-const uint8_t TableNotFoundException::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
+AccumuloSecurityException::AccumuloSecurityException(const AccumuloSecurityException& other181) : TException() {
+  msg = other181.msg;
+  __isset = other181.__isset;
+}
+AccumuloSecurityException& AccumuloSecurityException::operator=(const AccumuloSecurityException& other182) {
+  msg = other182.msg;
+  __isset = other182.__isset;
+  return *this;
+}
+void AccumuloSecurityException::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "AccumuloSecurityException(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* AccumuloSecurityException::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: AccumuloSecurityException";
+  }
+}
+
+
+TableNotFoundException::~TableNotFoundException() throw() {
+}
+
+
+void TableNotFoundException::__set_msg(const std::string& val) {
+  this->msg = val;
+}
 
 uint32_t TableNotFoundException::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3073,6 +4235,7 @@
 
 uint32_t TableNotFoundException::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("TableNotFoundException");
 
   xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
@@ -3090,11 +4253,45 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* TableExistsException::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1";
-const uint8_t TableExistsException::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
+TableNotFoundException::TableNotFoundException(const TableNotFoundException& other183) : TException() {
+  msg = other183.msg;
+  __isset = other183.__isset;
+}
+TableNotFoundException& TableNotFoundException::operator=(const TableNotFoundException& other184) {
+  msg = other184.msg;
+  __isset = other184.__isset;
+  return *this;
+}
+void TableNotFoundException::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "TableNotFoundException(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* TableNotFoundException::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: TableNotFoundException";
+  }
+}
+
+
+TableExistsException::~TableExistsException() throw() {
+}
+
+
+void TableExistsException::__set_msg(const std::string& val) {
+  this->msg = val;
+}
 
 uint32_t TableExistsException::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3135,6 +4332,7 @@
 
 uint32_t TableExistsException::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("TableExistsException");
 
   xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
@@ -3152,11 +4350,45 @@
   swap(a.__isset, b.__isset);
 }
 
-const char* MutationsRejectedException::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1";
-const uint8_t MutationsRejectedException::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
+TableExistsException::TableExistsException(const TableExistsException& other185) : TException() {
+  msg = other185.msg;
+  __isset = other185.__isset;
+}
+TableExistsException& TableExistsException::operator=(const TableExistsException& other186) {
+  msg = other186.msg;
+  __isset = other186.__isset;
+  return *this;
+}
+void TableExistsException::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "TableExistsException(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* TableExistsException::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: TableExistsException";
+  }
+}
+
+
+MutationsRejectedException::~MutationsRejectedException() throw() {
+}
+
+
+void MutationsRejectedException::__set_msg(const std::string& val) {
+  this->msg = val;
+}
 
 uint32_t MutationsRejectedException::read(::apache::thrift::protocol::TProtocol* iprot) {
 
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
   uint32_t xfer = 0;
   std::string fname;
   ::apache::thrift::protocol::TType ftype;
@@ -3197,6 +4429,7 @@
 
 uint32_t MutationsRejectedException::write(::apache::thrift::protocol::TProtocol* oprot) const {
   uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
   xfer += oprot->writeStructBegin("MutationsRejectedException");
 
   xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
@@ -3214,4 +4447,322 @@
   swap(a.__isset, b.__isset);
 }
 
+MutationsRejectedException::MutationsRejectedException(const MutationsRejectedException& other187) : TException() {
+  msg = other187.msg;
+  __isset = other187.__isset;
+}
+MutationsRejectedException& MutationsRejectedException::operator=(const MutationsRejectedException& other188) {
+  msg = other188.msg;
+  __isset = other188.__isset;
+  return *this;
+}
+void MutationsRejectedException::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "MutationsRejectedException(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* MutationsRejectedException::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: MutationsRejectedException";
+  }
+}
+
+
+NamespaceExistsException::~NamespaceExistsException() throw() {
+}
+
+
+void NamespaceExistsException::__set_msg(const std::string& val) {
+  this->msg = val;
+}
+
+uint32_t NamespaceExistsException::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->msg);
+          this->__isset.msg = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t NamespaceExistsException::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("NamespaceExistsException");
+
+  xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeString(this->msg);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+void swap(NamespaceExistsException &a, NamespaceExistsException &b) {
+  using ::std::swap;
+  swap(a.msg, b.msg);
+  swap(a.__isset, b.__isset);
+}
+
+NamespaceExistsException::NamespaceExistsException(const NamespaceExistsException& other189) : TException() {
+  msg = other189.msg;
+  __isset = other189.__isset;
+}
+NamespaceExistsException& NamespaceExistsException::operator=(const NamespaceExistsException& other190) {
+  msg = other190.msg;
+  __isset = other190.__isset;
+  return *this;
+}
+void NamespaceExistsException::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "NamespaceExistsException(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* NamespaceExistsException::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: NamespaceExistsException";
+  }
+}
+
+
+NamespaceNotFoundException::~NamespaceNotFoundException() throw() {
+}
+
+
+void NamespaceNotFoundException::__set_msg(const std::string& val) {
+  this->msg = val;
+}
+
+uint32_t NamespaceNotFoundException::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->msg);
+          this->__isset.msg = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t NamespaceNotFoundException::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("NamespaceNotFoundException");
+
+  xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeString(this->msg);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+void swap(NamespaceNotFoundException &a, NamespaceNotFoundException &b) {
+  using ::std::swap;
+  swap(a.msg, b.msg);
+  swap(a.__isset, b.__isset);
+}
+
+NamespaceNotFoundException::NamespaceNotFoundException(const NamespaceNotFoundException& other191) : TException() {
+  msg = other191.msg;
+  __isset = other191.__isset;
+}
+NamespaceNotFoundException& NamespaceNotFoundException::operator=(const NamespaceNotFoundException& other192) {
+  msg = other192.msg;
+  __isset = other192.__isset;
+  return *this;
+}
+void NamespaceNotFoundException::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "NamespaceNotFoundException(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* NamespaceNotFoundException::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: NamespaceNotFoundException";
+  }
+}
+
+
+NamespaceNotEmptyException::~NamespaceNotEmptyException() throw() {
+}
+
+
+void NamespaceNotEmptyException::__set_msg(const std::string& val) {
+  this->msg = val;
+}
+
+uint32_t NamespaceNotEmptyException::read(::apache::thrift::protocol::TProtocol* iprot) {
+
+  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
+  uint32_t xfer = 0;
+  std::string fname;
+  ::apache::thrift::protocol::TType ftype;
+  int16_t fid;
+
+  xfer += iprot->readStructBegin(fname);
+
+  using ::apache::thrift::protocol::TProtocolException;
+
+
+  while (true)
+  {
+    xfer += iprot->readFieldBegin(fname, ftype, fid);
+    if (ftype == ::apache::thrift::protocol::T_STOP) {
+      break;
+    }
+    switch (fid)
+    {
+      case 1:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->msg);
+          this->__isset.msg = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
+      default:
+        xfer += iprot->skip(ftype);
+        break;
+    }
+    xfer += iprot->readFieldEnd();
+  }
+
+  xfer += iprot->readStructEnd();
+
+  return xfer;
+}
+
+uint32_t NamespaceNotEmptyException::write(::apache::thrift::protocol::TProtocol* oprot) const {
+  uint32_t xfer = 0;
+  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
+  xfer += oprot->writeStructBegin("NamespaceNotEmptyException");
+
+  xfer += oprot->writeFieldBegin("msg", ::apache::thrift::protocol::T_STRING, 1);
+  xfer += oprot->writeString(this->msg);
+  xfer += oprot->writeFieldEnd();
+
+  xfer += oprot->writeFieldStop();
+  xfer += oprot->writeStructEnd();
+  return xfer;
+}
+
+void swap(NamespaceNotEmptyException &a, NamespaceNotEmptyException &b) {
+  using ::std::swap;
+  swap(a.msg, b.msg);
+  swap(a.__isset, b.__isset);
+}
+
+NamespaceNotEmptyException::NamespaceNotEmptyException(const NamespaceNotEmptyException& other193) : TException() {
+  msg = other193.msg;
+  __isset = other193.__isset;
+}
+NamespaceNotEmptyException& NamespaceNotEmptyException::operator=(const NamespaceNotEmptyException& other194) {
+  msg = other194.msg;
+  __isset = other194.__isset;
+  return *this;
+}
+void NamespaceNotEmptyException::printTo(std::ostream& out) const {
+  using ::apache::thrift::to_string;
+  out << "NamespaceNotEmptyException(";
+  out << "msg=" << to_string(msg);
+  out << ")";
+}
+
+const char* NamespaceNotEmptyException::what() const throw() {
+  try {
+    std::stringstream ss;
+    ss << "TException - service has thrown: " << *this;
+    this->thriftTExceptionMessageHolder_ = ss.str();
+    return this->thriftTExceptionMessageHolder_.c_str();
+  } catch (const std::exception&) {
+    return "TException - service has thrown: NamespaceNotEmptyException";
+  }
+}
+
 } // namespace
diff --git a/src/main/cpp/proxy_types.h b/src/main/cpp/proxy_types.h
index c0169ef..6c02404 100644
--- a/src/main/cpp/proxy_types.h
+++ b/src/main/cpp/proxy_types.h
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,6 +23,8 @@
 #ifndef proxy_TYPES_H
 #define proxy_TYPES_H
 
+#include <iosfwd>
+
 #include <thrift/Thrift.h>
 #include <thrift/TApplicationException.h>
 #include <thrift/protocol/TProtocol.h>
@@ -78,6 +80,22 @@
 
 extern const std::map<int, const char*> _SystemPermission_VALUES_TO_NAMES;
 
+struct NamespacePermission {
+  enum type {
+    READ = 0,
+    WRITE = 1,
+    ALTER_NAMESPACE = 2,
+    GRANT = 3,
+    ALTER_TABLE = 4,
+    CREATE_TABLE = 5,
+    DROP_TABLE = 6,
+    BULK_IMPORT = 7,
+    DROP_NAMESPACE = 8
+  };
+};
+
+extern const std::map<int, const char*> _NamespacePermission_VALUES_TO_NAMES;
+
 struct ScanType {
   enum type {
     SINGLE = 0,
@@ -163,26 +181,86 @@
 
 extern const std::map<int, const char*> _TimeType_VALUES_TO_NAMES;
 
+class Key;
+
+class ColumnUpdate;
+
+class DiskUsage;
+
+class KeyValue;
+
+class ScanResult;
+
+class Range;
+
+class ScanColumn;
+
+class IteratorSetting;
+
+class ScanOptions;
+
+class BatchScanOptions;
+
+class KeyValueAndPeek;
+
+class KeyExtent;
+
+class Column;
+
+class Condition;
+
+class ConditionalUpdates;
+
+class ConditionalWriterOptions;
+
+class ActiveScan;
+
+class ActiveCompaction;
+
+class WriterOptions;
+
+class CompactionStrategyConfig;
+
+class UnknownScanner;
+
+class UnknownWriter;
+
+class NoMoreEntriesException;
+
+class AccumuloException;
+
+class AccumuloSecurityException;
+
+class TableNotFoundException;
+
+class TableExistsException;
+
+class MutationsRejectedException;
+
+class NamespaceExistsException;
+
+class NamespaceNotFoundException;
+
+class NamespaceNotEmptyException;
+
 typedef struct _Key__isset {
   _Key__isset() : row(false), colFamily(false), colQualifier(false), colVisibility(false), timestamp(true) {}
-  bool row;
-  bool colFamily;
-  bool colQualifier;
-  bool colVisibility;
-  bool timestamp;
+  bool row :1;
+  bool colFamily :1;
+  bool colQualifier :1;
+  bool colVisibility :1;
+  bool timestamp :1;
 } _Key__isset;
 
 class Key {
  public:
 
-  static const char* ascii_fingerprint; // = "91151A432E03F5E8564877B5194B48E2";
-  static const uint8_t binary_fingerprint[16]; // = {0x91,0x15,0x1A,0x43,0x2E,0x03,0xF5,0xE8,0x56,0x48,0x77,0xB5,0x19,0x4B,0x48,0xE2};
-
+  Key(const Key&);
+  Key& operator=(const Key&);
   Key() : row(), colFamily(), colQualifier(), colVisibility(), timestamp(9223372036854775807LL) {
   }
 
-  virtual ~Key() throw() {}
-
+  virtual ~Key() throw();
   std::string row;
   std::string colFamily;
   std::string colQualifier;
@@ -191,26 +269,15 @@
 
   _Key__isset __isset;
 
-  void __set_row(const std::string& val) {
-    row = val;
-  }
+  void __set_row(const std::string& val);
 
-  void __set_colFamily(const std::string& val) {
-    colFamily = val;
-  }
+  void __set_colFamily(const std::string& val);
 
-  void __set_colQualifier(const std::string& val) {
-    colQualifier = val;
-  }
+  void __set_colQualifier(const std::string& val);
 
-  void __set_colVisibility(const std::string& val) {
-    colVisibility = val;
-  }
+  void __set_colVisibility(const std::string& val);
 
-  void __set_timestamp(const int64_t val) {
-    timestamp = val;
-    __isset.timestamp = true;
-  }
+  void __set_timestamp(const int64_t val);
 
   bool operator == (const Key & rhs) const
   {
@@ -237,31 +304,36 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(Key &a, Key &b);
 
+inline std::ostream& operator<<(std::ostream& out, const Key& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _ColumnUpdate__isset {
   _ColumnUpdate__isset() : colFamily(false), colQualifier(false), colVisibility(false), timestamp(false), value(false), deleteCell(false) {}
-  bool colFamily;
-  bool colQualifier;
-  bool colVisibility;
-  bool timestamp;
-  bool value;
-  bool deleteCell;
+  bool colFamily :1;
+  bool colQualifier :1;
+  bool colVisibility :1;
+  bool timestamp :1;
+  bool value :1;
+  bool deleteCell :1;
 } _ColumnUpdate__isset;
 
 class ColumnUpdate {
  public:
 
-  static const char* ascii_fingerprint; // = "65CC1863F7DDC1DE75B9EAF9E2DC0D1F";
-  static const uint8_t binary_fingerprint[16]; // = {0x65,0xCC,0x18,0x63,0xF7,0xDD,0xC1,0xDE,0x75,0xB9,0xEA,0xF9,0xE2,0xDC,0x0D,0x1F};
-
+  ColumnUpdate(const ColumnUpdate&);
+  ColumnUpdate& operator=(const ColumnUpdate&);
   ColumnUpdate() : colFamily(), colQualifier(), colVisibility(), timestamp(0), value(), deleteCell(0) {
   }
 
-  virtual ~ColumnUpdate() throw() {}
-
+  virtual ~ColumnUpdate() throw();
   std::string colFamily;
   std::string colQualifier;
   std::string colVisibility;
@@ -271,33 +343,17 @@
 
   _ColumnUpdate__isset __isset;
 
-  void __set_colFamily(const std::string& val) {
-    colFamily = val;
-  }
+  void __set_colFamily(const std::string& val);
 
-  void __set_colQualifier(const std::string& val) {
-    colQualifier = val;
-  }
+  void __set_colQualifier(const std::string& val);
 
-  void __set_colVisibility(const std::string& val) {
-    colVisibility = val;
-    __isset.colVisibility = true;
-  }
+  void __set_colVisibility(const std::string& val);
 
-  void __set_timestamp(const int64_t val) {
-    timestamp = val;
-    __isset.timestamp = true;
-  }
+  void __set_timestamp(const int64_t val);
 
-  void __set_value(const std::string& val) {
-    value = val;
-    __isset.value = true;
-  }
+  void __set_value(const std::string& val);
 
-  void __set_deleteCell(const bool val) {
-    deleteCell = val;
-    __isset.deleteCell = true;
-  }
+  void __set_deleteCell(const bool val);
 
   bool operator == (const ColumnUpdate & rhs) const
   {
@@ -332,39 +388,40 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(ColumnUpdate &a, ColumnUpdate &b);
 
+inline std::ostream& operator<<(std::ostream& out, const ColumnUpdate& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _DiskUsage__isset {
   _DiskUsage__isset() : tables(false), usage(false) {}
-  bool tables;
-  bool usage;
+  bool tables :1;
+  bool usage :1;
 } _DiskUsage__isset;
 
 class DiskUsage {
  public:
 
-  static const char* ascii_fingerprint; // = "D26F4F5E2867D41CF7E0391263932D6B";
-  static const uint8_t binary_fingerprint[16]; // = {0xD2,0x6F,0x4F,0x5E,0x28,0x67,0xD4,0x1C,0xF7,0xE0,0x39,0x12,0x63,0x93,0x2D,0x6B};
-
+  DiskUsage(const DiskUsage&);
+  DiskUsage& operator=(const DiskUsage&);
   DiskUsage() : usage(0) {
   }
 
-  virtual ~DiskUsage() throw() {}
-
+  virtual ~DiskUsage() throw();
   std::vector<std::string>  tables;
   int64_t usage;
 
   _DiskUsage__isset __isset;
 
-  void __set_tables(const std::vector<std::string> & val) {
-    tables = val;
-  }
+  void __set_tables(const std::vector<std::string> & val);
 
-  void __set_usage(const int64_t val) {
-    usage = val;
-  }
+  void __set_usage(const int64_t val);
 
   bool operator == (const DiskUsage & rhs) const
   {
@@ -383,39 +440,40 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(DiskUsage &a, DiskUsage &b);
 
+inline std::ostream& operator<<(std::ostream& out, const DiskUsage& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _KeyValue__isset {
   _KeyValue__isset() : key(false), value(false) {}
-  bool key;
-  bool value;
+  bool key :1;
+  bool value :1;
 } _KeyValue__isset;
 
 class KeyValue {
  public:
 
-  static const char* ascii_fingerprint; // = "0D0CA44F233F983E00E94228C31ABBD4";
-  static const uint8_t binary_fingerprint[16]; // = {0x0D,0x0C,0xA4,0x4F,0x23,0x3F,0x98,0x3E,0x00,0xE9,0x42,0x28,0xC3,0x1A,0xBB,0xD4};
-
+  KeyValue(const KeyValue&);
+  KeyValue& operator=(const KeyValue&);
   KeyValue() : value() {
   }
 
-  virtual ~KeyValue() throw() {}
-
+  virtual ~KeyValue() throw();
   Key key;
   std::string value;
 
   _KeyValue__isset __isset;
 
-  void __set_key(const Key& val) {
-    key = val;
-  }
+  void __set_key(const Key& val);
 
-  void __set_value(const std::string& val) {
-    value = val;
-  }
+  void __set_value(const std::string& val);
 
   bool operator == (const KeyValue & rhs) const
   {
@@ -434,39 +492,40 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(KeyValue &a, KeyValue &b);
 
+inline std::ostream& operator<<(std::ostream& out, const KeyValue& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _ScanResult__isset {
   _ScanResult__isset() : results(false), more(false) {}
-  bool results;
-  bool more;
+  bool results :1;
+  bool more :1;
 } _ScanResult__isset;
 
 class ScanResult {
  public:
 
-  static const char* ascii_fingerprint; // = "684A3FCA76EA202FE071A17F8B510E7A";
-  static const uint8_t binary_fingerprint[16]; // = {0x68,0x4A,0x3F,0xCA,0x76,0xEA,0x20,0x2F,0xE0,0x71,0xA1,0x7F,0x8B,0x51,0x0E,0x7A};
-
+  ScanResult(const ScanResult&);
+  ScanResult& operator=(const ScanResult&);
   ScanResult() : more(0) {
   }
 
-  virtual ~ScanResult() throw() {}
-
+  virtual ~ScanResult() throw();
   std::vector<KeyValue>  results;
   bool more;
 
   _ScanResult__isset __isset;
 
-  void __set_results(const std::vector<KeyValue> & val) {
-    results = val;
-  }
+  void __set_results(const std::vector<KeyValue> & val);
 
-  void __set_more(const bool val) {
-    more = val;
-  }
+  void __set_more(const bool val);
 
   bool operator == (const ScanResult & rhs) const
   {
@@ -485,29 +544,34 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(ScanResult &a, ScanResult &b);
 
+inline std::ostream& operator<<(std::ostream& out, const ScanResult& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _Range__isset {
   _Range__isset() : start(false), startInclusive(false), stop(false), stopInclusive(false) {}
-  bool start;
-  bool startInclusive;
-  bool stop;
-  bool stopInclusive;
+  bool start :1;
+  bool startInclusive :1;
+  bool stop :1;
+  bool stopInclusive :1;
 } _Range__isset;
 
 class Range {
  public:
 
-  static const char* ascii_fingerprint; // = "84C5BA8DB718E60BFBF3F83867647B45";
-  static const uint8_t binary_fingerprint[16]; // = {0x84,0xC5,0xBA,0x8D,0xB7,0x18,0xE6,0x0B,0xFB,0xF3,0xF8,0x38,0x67,0x64,0x7B,0x45};
-
+  Range(const Range&);
+  Range& operator=(const Range&);
   Range() : startInclusive(0), stopInclusive(0) {
   }
 
-  virtual ~Range() throw() {}
-
+  virtual ~Range() throw();
   Key start;
   bool startInclusive;
   Key stop;
@@ -515,21 +579,13 @@
 
   _Range__isset __isset;
 
-  void __set_start(const Key& val) {
-    start = val;
-  }
+  void __set_start(const Key& val);
 
-  void __set_startInclusive(const bool val) {
-    startInclusive = val;
-  }
+  void __set_startInclusive(const bool val);
 
-  void __set_stop(const Key& val) {
-    stop = val;
-  }
+  void __set_stop(const Key& val);
 
-  void __set_stopInclusive(const bool val) {
-    stopInclusive = val;
-  }
+  void __set_stopInclusive(const bool val);
 
   bool operator == (const Range & rhs) const
   {
@@ -552,40 +608,40 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(Range &a, Range &b);
 
+inline std::ostream& operator<<(std::ostream& out, const Range& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _ScanColumn__isset {
   _ScanColumn__isset() : colFamily(false), colQualifier(false) {}
-  bool colFamily;
-  bool colQualifier;
+  bool colFamily :1;
+  bool colQualifier :1;
 } _ScanColumn__isset;
 
 class ScanColumn {
  public:
 
-  static const char* ascii_fingerprint; // = "5B708A954C550ECA9C1A49D3C5CAFAB9";
-  static const uint8_t binary_fingerprint[16]; // = {0x5B,0x70,0x8A,0x95,0x4C,0x55,0x0E,0xCA,0x9C,0x1A,0x49,0xD3,0xC5,0xCA,0xFA,0xB9};
-
+  ScanColumn(const ScanColumn&);
+  ScanColumn& operator=(const ScanColumn&);
   ScanColumn() : colFamily(), colQualifier() {
   }
 
-  virtual ~ScanColumn() throw() {}
-
+  virtual ~ScanColumn() throw();
   std::string colFamily;
   std::string colQualifier;
 
   _ScanColumn__isset __isset;
 
-  void __set_colFamily(const std::string& val) {
-    colFamily = val;
-  }
+  void __set_colFamily(const std::string& val);
 
-  void __set_colQualifier(const std::string& val) {
-    colQualifier = val;
-    __isset.colQualifier = true;
-  }
+  void __set_colQualifier(const std::string& val);
 
   bool operator == (const ScanColumn & rhs) const
   {
@@ -606,29 +662,34 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(ScanColumn &a, ScanColumn &b);
 
+inline std::ostream& operator<<(std::ostream& out, const ScanColumn& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _IteratorSetting__isset {
   _IteratorSetting__isset() : priority(false), name(false), iteratorClass(false), properties(false) {}
-  bool priority;
-  bool name;
-  bool iteratorClass;
-  bool properties;
+  bool priority :1;
+  bool name :1;
+  bool iteratorClass :1;
+  bool properties :1;
 } _IteratorSetting__isset;
 
 class IteratorSetting {
  public:
 
-  static const char* ascii_fingerprint; // = "985C857916964E43205EAC92A157CB4E";
-  static const uint8_t binary_fingerprint[16]; // = {0x98,0x5C,0x85,0x79,0x16,0x96,0x4E,0x43,0x20,0x5E,0xAC,0x92,0xA1,0x57,0xCB,0x4E};
-
+  IteratorSetting(const IteratorSetting&);
+  IteratorSetting& operator=(const IteratorSetting&);
   IteratorSetting() : priority(0), name(), iteratorClass() {
   }
 
-  virtual ~IteratorSetting() throw() {}
-
+  virtual ~IteratorSetting() throw();
   int32_t priority;
   std::string name;
   std::string iteratorClass;
@@ -636,21 +697,13 @@
 
   _IteratorSetting__isset __isset;
 
-  void __set_priority(const int32_t val) {
-    priority = val;
-  }
+  void __set_priority(const int32_t val);
 
-  void __set_name(const std::string& val) {
-    name = val;
-  }
+  void __set_name(const std::string& val);
 
-  void __set_iteratorClass(const std::string& val) {
-    iteratorClass = val;
-  }
+  void __set_iteratorClass(const std::string& val);
 
-  void __set_properties(const std::map<std::string, std::string> & val) {
-    properties = val;
-  }
+  void __set_properties(const std::map<std::string, std::string> & val);
 
   bool operator == (const IteratorSetting & rhs) const
   {
@@ -673,30 +726,35 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(IteratorSetting &a, IteratorSetting &b);
 
+inline std::ostream& operator<<(std::ostream& out, const IteratorSetting& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _ScanOptions__isset {
   _ScanOptions__isset() : authorizations(false), range(false), columns(false), iterators(false), bufferSize(false) {}
-  bool authorizations;
-  bool range;
-  bool columns;
-  bool iterators;
-  bool bufferSize;
+  bool authorizations :1;
+  bool range :1;
+  bool columns :1;
+  bool iterators :1;
+  bool bufferSize :1;
 } _ScanOptions__isset;
 
 class ScanOptions {
  public:
 
-  static const char* ascii_fingerprint; // = "3D87D0CD05FA62E15880C4D2C595907C";
-  static const uint8_t binary_fingerprint[16]; // = {0x3D,0x87,0xD0,0xCD,0x05,0xFA,0x62,0xE1,0x58,0x80,0xC4,0xD2,0xC5,0x95,0x90,0x7C};
-
+  ScanOptions(const ScanOptions&);
+  ScanOptions& operator=(const ScanOptions&);
   ScanOptions() : bufferSize(0) {
   }
 
-  virtual ~ScanOptions() throw() {}
-
+  virtual ~ScanOptions() throw();
   std::set<std::string>  authorizations;
   Range range;
   std::vector<ScanColumn>  columns;
@@ -705,30 +763,15 @@
 
   _ScanOptions__isset __isset;
 
-  void __set_authorizations(const std::set<std::string> & val) {
-    authorizations = val;
-    __isset.authorizations = true;
-  }
+  void __set_authorizations(const std::set<std::string> & val);
 
-  void __set_range(const Range& val) {
-    range = val;
-    __isset.range = true;
-  }
+  void __set_range(const Range& val);
 
-  void __set_columns(const std::vector<ScanColumn> & val) {
-    columns = val;
-    __isset.columns = true;
-  }
+  void __set_columns(const std::vector<ScanColumn> & val);
 
-  void __set_iterators(const std::vector<IteratorSetting> & val) {
-    iterators = val;
-    __isset.iterators = true;
-  }
+  void __set_iterators(const std::vector<IteratorSetting> & val);
 
-  void __set_bufferSize(const int32_t val) {
-    bufferSize = val;
-    __isset.bufferSize = true;
-  }
+  void __set_bufferSize(const int32_t val);
 
   bool operator == (const ScanOptions & rhs) const
   {
@@ -763,30 +806,35 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(ScanOptions &a, ScanOptions &b);
 
+inline std::ostream& operator<<(std::ostream& out, const ScanOptions& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _BatchScanOptions__isset {
   _BatchScanOptions__isset() : authorizations(false), ranges(false), columns(false), iterators(false), threads(false) {}
-  bool authorizations;
-  bool ranges;
-  bool columns;
-  bool iterators;
-  bool threads;
+  bool authorizations :1;
+  bool ranges :1;
+  bool columns :1;
+  bool iterators :1;
+  bool threads :1;
 } _BatchScanOptions__isset;
 
 class BatchScanOptions {
  public:
 
-  static const char* ascii_fingerprint; // = "6ADFA1FBE31B1220D2C103284E002308";
-  static const uint8_t binary_fingerprint[16]; // = {0x6A,0xDF,0xA1,0xFB,0xE3,0x1B,0x12,0x20,0xD2,0xC1,0x03,0x28,0x4E,0x00,0x23,0x08};
-
+  BatchScanOptions(const BatchScanOptions&);
+  BatchScanOptions& operator=(const BatchScanOptions&);
   BatchScanOptions() : threads(0) {
   }
 
-  virtual ~BatchScanOptions() throw() {}
-
+  virtual ~BatchScanOptions() throw();
   std::set<std::string>  authorizations;
   std::vector<Range>  ranges;
   std::vector<ScanColumn>  columns;
@@ -795,30 +843,15 @@
 
   _BatchScanOptions__isset __isset;
 
-  void __set_authorizations(const std::set<std::string> & val) {
-    authorizations = val;
-    __isset.authorizations = true;
-  }
+  void __set_authorizations(const std::set<std::string> & val);
 
-  void __set_ranges(const std::vector<Range> & val) {
-    ranges = val;
-    __isset.ranges = true;
-  }
+  void __set_ranges(const std::vector<Range> & val);
 
-  void __set_columns(const std::vector<ScanColumn> & val) {
-    columns = val;
-    __isset.columns = true;
-  }
+  void __set_columns(const std::vector<ScanColumn> & val);
 
-  void __set_iterators(const std::vector<IteratorSetting> & val) {
-    iterators = val;
-    __isset.iterators = true;
-  }
+  void __set_iterators(const std::vector<IteratorSetting> & val);
 
-  void __set_threads(const int32_t val) {
-    threads = val;
-    __isset.threads = true;
-  }
+  void __set_threads(const int32_t val);
 
   bool operator == (const BatchScanOptions & rhs) const
   {
@@ -853,39 +886,40 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(BatchScanOptions &a, BatchScanOptions &b);
 
+inline std::ostream& operator<<(std::ostream& out, const BatchScanOptions& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _KeyValueAndPeek__isset {
   _KeyValueAndPeek__isset() : keyValue(false), hasNext(false) {}
-  bool keyValue;
-  bool hasNext;
+  bool keyValue :1;
+  bool hasNext :1;
 } _KeyValueAndPeek__isset;
 
 class KeyValueAndPeek {
  public:
 
-  static const char* ascii_fingerprint; // = "CBBC6AB9C7EA5E5E748C13F970862FAB";
-  static const uint8_t binary_fingerprint[16]; // = {0xCB,0xBC,0x6A,0xB9,0xC7,0xEA,0x5E,0x5E,0x74,0x8C,0x13,0xF9,0x70,0x86,0x2F,0xAB};
-
+  KeyValueAndPeek(const KeyValueAndPeek&);
+  KeyValueAndPeek& operator=(const KeyValueAndPeek&);
   KeyValueAndPeek() : hasNext(0) {
   }
 
-  virtual ~KeyValueAndPeek() throw() {}
-
+  virtual ~KeyValueAndPeek() throw();
   KeyValue keyValue;
   bool hasNext;
 
   _KeyValueAndPeek__isset __isset;
 
-  void __set_keyValue(const KeyValue& val) {
-    keyValue = val;
-  }
+  void __set_keyValue(const KeyValue& val);
 
-  void __set_hasNext(const bool val) {
-    hasNext = val;
-  }
+  void __set_hasNext(const bool val);
 
   bool operator == (const KeyValueAndPeek & rhs) const
   {
@@ -904,45 +938,44 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(KeyValueAndPeek &a, KeyValueAndPeek &b);
 
+inline std::ostream& operator<<(std::ostream& out, const KeyValueAndPeek& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _KeyExtent__isset {
   _KeyExtent__isset() : tableId(false), endRow(false), prevEndRow(false) {}
-  bool tableId;
-  bool endRow;
-  bool prevEndRow;
+  bool tableId :1;
+  bool endRow :1;
+  bool prevEndRow :1;
 } _KeyExtent__isset;
 
 class KeyExtent {
  public:
 
-  static const char* ascii_fingerprint; // = "AB879940BD15B6B25691265F7384B271";
-  static const uint8_t binary_fingerprint[16]; // = {0xAB,0x87,0x99,0x40,0xBD,0x15,0xB6,0xB2,0x56,0x91,0x26,0x5F,0x73,0x84,0xB2,0x71};
-
+  KeyExtent(const KeyExtent&);
+  KeyExtent& operator=(const KeyExtent&);
   KeyExtent() : tableId(), endRow(), prevEndRow() {
   }
 
-  virtual ~KeyExtent() throw() {}
-
+  virtual ~KeyExtent() throw();
   std::string tableId;
   std::string endRow;
   std::string prevEndRow;
 
   _KeyExtent__isset __isset;
 
-  void __set_tableId(const std::string& val) {
-    tableId = val;
-  }
+  void __set_tableId(const std::string& val);
 
-  void __set_endRow(const std::string& val) {
-    endRow = val;
-  }
+  void __set_endRow(const std::string& val);
 
-  void __set_prevEndRow(const std::string& val) {
-    prevEndRow = val;
-  }
+  void __set_prevEndRow(const std::string& val);
 
   bool operator == (const KeyExtent & rhs) const
   {
@@ -963,45 +996,44 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(KeyExtent &a, KeyExtent &b);
 
+inline std::ostream& operator<<(std::ostream& out, const KeyExtent& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _Column__isset {
   _Column__isset() : colFamily(false), colQualifier(false), colVisibility(false) {}
-  bool colFamily;
-  bool colQualifier;
-  bool colVisibility;
+  bool colFamily :1;
+  bool colQualifier :1;
+  bool colVisibility :1;
 } _Column__isset;
 
 class Column {
  public:
 
-  static const char* ascii_fingerprint; // = "AB879940BD15B6B25691265F7384B271";
-  static const uint8_t binary_fingerprint[16]; // = {0xAB,0x87,0x99,0x40,0xBD,0x15,0xB6,0xB2,0x56,0x91,0x26,0x5F,0x73,0x84,0xB2,0x71};
-
+  Column(const Column&);
+  Column& operator=(const Column&);
   Column() : colFamily(), colQualifier(), colVisibility() {
   }
 
-  virtual ~Column() throw() {}
-
+  virtual ~Column() throw();
   std::string colFamily;
   std::string colQualifier;
   std::string colVisibility;
 
   _Column__isset __isset;
 
-  void __set_colFamily(const std::string& val) {
-    colFamily = val;
-  }
+  void __set_colFamily(const std::string& val);
 
-  void __set_colQualifier(const std::string& val) {
-    colQualifier = val;
-  }
+  void __set_colQualifier(const std::string& val);
 
-  void __set_colVisibility(const std::string& val) {
-    colVisibility = val;
-  }
+  void __set_colVisibility(const std::string& val);
 
   bool operator == (const Column & rhs) const
   {
@@ -1022,29 +1054,34 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(Column &a, Column &b);
 
+inline std::ostream& operator<<(std::ostream& out, const Column& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _Condition__isset {
   _Condition__isset() : column(false), timestamp(false), value(false), iterators(false) {}
-  bool column;
-  bool timestamp;
-  bool value;
-  bool iterators;
+  bool column :1;
+  bool timestamp :1;
+  bool value :1;
+  bool iterators :1;
 } _Condition__isset;
 
 class Condition {
  public:
 
-  static const char* ascii_fingerprint; // = "C4022914C22D89E33B1A46A7D511C58F";
-  static const uint8_t binary_fingerprint[16]; // = {0xC4,0x02,0x29,0x14,0xC2,0x2D,0x89,0xE3,0x3B,0x1A,0x46,0xA7,0xD5,0x11,0xC5,0x8F};
-
+  Condition(const Condition&);
+  Condition& operator=(const Condition&);
   Condition() : timestamp(0), value() {
   }
 
-  virtual ~Condition() throw() {}
-
+  virtual ~Condition() throw();
   Column column;
   int64_t timestamp;
   std::string value;
@@ -1052,24 +1089,13 @@
 
   _Condition__isset __isset;
 
-  void __set_column(const Column& val) {
-    column = val;
-  }
+  void __set_column(const Column& val);
 
-  void __set_timestamp(const int64_t val) {
-    timestamp = val;
-    __isset.timestamp = true;
-  }
+  void __set_timestamp(const int64_t val);
 
-  void __set_value(const std::string& val) {
-    value = val;
-    __isset.value = true;
-  }
+  void __set_value(const std::string& val);
 
-  void __set_iterators(const std::vector<IteratorSetting> & val) {
-    iterators = val;
-    __isset.iterators = true;
-  }
+  void __set_iterators(const std::vector<IteratorSetting> & val);
 
   bool operator == (const Condition & rhs) const
   {
@@ -1098,39 +1124,40 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(Condition &a, Condition &b);
 
+inline std::ostream& operator<<(std::ostream& out, const Condition& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _ConditionalUpdates__isset {
   _ConditionalUpdates__isset() : conditions(false), updates(false) {}
-  bool conditions;
-  bool updates;
+  bool conditions :1;
+  bool updates :1;
 } _ConditionalUpdates__isset;
 
 class ConditionalUpdates {
  public:
 
-  static const char* ascii_fingerprint; // = "1C1808872D1A8E04F114974ADD77F356";
-  static const uint8_t binary_fingerprint[16]; // = {0x1C,0x18,0x08,0x87,0x2D,0x1A,0x8E,0x04,0xF1,0x14,0x97,0x4A,0xDD,0x77,0xF3,0x56};
-
+  ConditionalUpdates(const ConditionalUpdates&);
+  ConditionalUpdates& operator=(const ConditionalUpdates&);
   ConditionalUpdates() {
   }
 
-  virtual ~ConditionalUpdates() throw() {}
-
+  virtual ~ConditionalUpdates() throw();
   std::vector<Condition>  conditions;
   std::vector<ColumnUpdate>  updates;
 
   _ConditionalUpdates__isset __isset;
 
-  void __set_conditions(const std::vector<Condition> & val) {
-    conditions = val;
-  }
+  void __set_conditions(const std::vector<Condition> & val);
 
-  void __set_updates(const std::vector<ColumnUpdate> & val) {
-    updates = val;
-  }
+  void __set_updates(const std::vector<ColumnUpdate> & val);
 
   bool operator == (const ConditionalUpdates & rhs) const
   {
@@ -1149,30 +1176,35 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(ConditionalUpdates &a, ConditionalUpdates &b);
 
+inline std::ostream& operator<<(std::ostream& out, const ConditionalUpdates& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _ConditionalWriterOptions__isset {
   _ConditionalWriterOptions__isset() : maxMemory(false), timeoutMs(false), threads(false), authorizations(false), durability(false) {}
-  bool maxMemory;
-  bool timeoutMs;
-  bool threads;
-  bool authorizations;
-  bool durability;
+  bool maxMemory :1;
+  bool timeoutMs :1;
+  bool threads :1;
+  bool authorizations :1;
+  bool durability :1;
 } _ConditionalWriterOptions__isset;
 
 class ConditionalWriterOptions {
  public:
 
-  static const char* ascii_fingerprint; // = "C345C04E84A351638B6EACB741BD600E";
-  static const uint8_t binary_fingerprint[16]; // = {0xC3,0x45,0xC0,0x4E,0x84,0xA3,0x51,0x63,0x8B,0x6E,0xAC,0xB7,0x41,0xBD,0x60,0x0E};
-
+  ConditionalWriterOptions(const ConditionalWriterOptions&);
+  ConditionalWriterOptions& operator=(const ConditionalWriterOptions&);
   ConditionalWriterOptions() : maxMemory(0), timeoutMs(0), threads(0), durability((Durability::type)0) {
   }
 
-  virtual ~ConditionalWriterOptions() throw() {}
-
+  virtual ~ConditionalWriterOptions() throw();
   int64_t maxMemory;
   int64_t timeoutMs;
   int32_t threads;
@@ -1181,30 +1213,15 @@
 
   _ConditionalWriterOptions__isset __isset;
 
-  void __set_maxMemory(const int64_t val) {
-    maxMemory = val;
-    __isset.maxMemory = true;
-  }
+  void __set_maxMemory(const int64_t val);
 
-  void __set_timeoutMs(const int64_t val) {
-    timeoutMs = val;
-    __isset.timeoutMs = true;
-  }
+  void __set_timeoutMs(const int64_t val);
 
-  void __set_threads(const int32_t val) {
-    threads = val;
-    __isset.threads = true;
-  }
+  void __set_threads(const int32_t val);
 
-  void __set_authorizations(const std::set<std::string> & val) {
-    authorizations = val;
-    __isset.authorizations = true;
-  }
+  void __set_authorizations(const std::set<std::string> & val);
 
-  void __set_durability(const Durability::type val) {
-    durability = val;
-    __isset.durability = true;
-  }
+  void __set_durability(const Durability::type val);
 
   bool operator == (const ConditionalWriterOptions & rhs) const
   {
@@ -1239,36 +1256,41 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(ConditionalWriterOptions &a, ConditionalWriterOptions &b);
 
+inline std::ostream& operator<<(std::ostream& out, const ConditionalWriterOptions& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _ActiveScan__isset {
   _ActiveScan__isset() : client(false), user(false), table(false), age(false), idleTime(false), type(false), state(false), extent(false), columns(false), iterators(false), authorizations(false) {}
-  bool client;
-  bool user;
-  bool table;
-  bool age;
-  bool idleTime;
-  bool type;
-  bool state;
-  bool extent;
-  bool columns;
-  bool iterators;
-  bool authorizations;
+  bool client :1;
+  bool user :1;
+  bool table :1;
+  bool age :1;
+  bool idleTime :1;
+  bool type :1;
+  bool state :1;
+  bool extent :1;
+  bool columns :1;
+  bool iterators :1;
+  bool authorizations :1;
 } _ActiveScan__isset;
 
 class ActiveScan {
  public:
 
-  static const char* ascii_fingerprint; // = "1B97541CB4E900A054266BBBEE61D004";
-  static const uint8_t binary_fingerprint[16]; // = {0x1B,0x97,0x54,0x1C,0xB4,0xE9,0x00,0xA0,0x54,0x26,0x6B,0xBB,0xEE,0x61,0xD0,0x04};
-
+  ActiveScan(const ActiveScan&);
+  ActiveScan& operator=(const ActiveScan&);
   ActiveScan() : client(), user(), table(), age(0), idleTime(0), type((ScanType::type)0), state((ScanState::type)0) {
   }
 
-  virtual ~ActiveScan() throw() {}
-
+  virtual ~ActiveScan() throw();
   std::string client;
   std::string user;
   std::string table;
@@ -1283,49 +1305,27 @@
 
   _ActiveScan__isset __isset;
 
-  void __set_client(const std::string& val) {
-    client = val;
-  }
+  void __set_client(const std::string& val);
 
-  void __set_user(const std::string& val) {
-    user = val;
-  }
+  void __set_user(const std::string& val);
 
-  void __set_table(const std::string& val) {
-    table = val;
-  }
+  void __set_table(const std::string& val);
 
-  void __set_age(const int64_t val) {
-    age = val;
-  }
+  void __set_age(const int64_t val);
 
-  void __set_idleTime(const int64_t val) {
-    idleTime = val;
-  }
+  void __set_idleTime(const int64_t val);
 
-  void __set_type(const ScanType::type val) {
-    type = val;
-  }
+  void __set_type(const ScanType::type val);
 
-  void __set_state(const ScanState::type val) {
-    state = val;
-  }
+  void __set_state(const ScanState::type val);
 
-  void __set_extent(const KeyExtent& val) {
-    extent = val;
-  }
+  void __set_extent(const KeyExtent& val);
 
-  void __set_columns(const std::vector<Column> & val) {
-    columns = val;
-  }
+  void __set_columns(const std::vector<Column> & val);
 
-  void __set_iterators(const std::vector<IteratorSetting> & val) {
-    iterators = val;
-  }
+  void __set_iterators(const std::vector<IteratorSetting> & val);
 
-  void __set_authorizations(const std::vector<std::string> & val) {
-    authorizations = val;
-  }
+  void __set_authorizations(const std::vector<std::string> & val);
 
   bool operator == (const ActiveScan & rhs) const
   {
@@ -1362,35 +1362,40 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(ActiveScan &a, ActiveScan &b);
 
+inline std::ostream& operator<<(std::ostream& out, const ActiveScan& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _ActiveCompaction__isset {
   _ActiveCompaction__isset() : extent(false), age(false), inputFiles(false), outputFile(false), type(false), reason(false), localityGroup(false), entriesRead(false), entriesWritten(false), iterators(false) {}
-  bool extent;
-  bool age;
-  bool inputFiles;
-  bool outputFile;
-  bool type;
-  bool reason;
-  bool localityGroup;
-  bool entriesRead;
-  bool entriesWritten;
-  bool iterators;
+  bool extent :1;
+  bool age :1;
+  bool inputFiles :1;
+  bool outputFile :1;
+  bool type :1;
+  bool reason :1;
+  bool localityGroup :1;
+  bool entriesRead :1;
+  bool entriesWritten :1;
+  bool iterators :1;
 } _ActiveCompaction__isset;
 
 class ActiveCompaction {
  public:
 
-  static const char* ascii_fingerprint; // = "2BB155CC901109464666B6C7E6A8C1A6";
-  static const uint8_t binary_fingerprint[16]; // = {0x2B,0xB1,0x55,0xCC,0x90,0x11,0x09,0x46,0x46,0x66,0xB6,0xC7,0xE6,0xA8,0xC1,0xA6};
-
+  ActiveCompaction(const ActiveCompaction&);
+  ActiveCompaction& operator=(const ActiveCompaction&);
   ActiveCompaction() : age(0), outputFile(), type((CompactionType::type)0), reason((CompactionReason::type)0), localityGroup(), entriesRead(0), entriesWritten(0) {
   }
 
-  virtual ~ActiveCompaction() throw() {}
-
+  virtual ~ActiveCompaction() throw();
   KeyExtent extent;
   int64_t age;
   std::vector<std::string>  inputFiles;
@@ -1404,45 +1409,25 @@
 
   _ActiveCompaction__isset __isset;
 
-  void __set_extent(const KeyExtent& val) {
-    extent = val;
-  }
+  void __set_extent(const KeyExtent& val);
 
-  void __set_age(const int64_t val) {
-    age = val;
-  }
+  void __set_age(const int64_t val);
 
-  void __set_inputFiles(const std::vector<std::string> & val) {
-    inputFiles = val;
-  }
+  void __set_inputFiles(const std::vector<std::string> & val);
 
-  void __set_outputFile(const std::string& val) {
-    outputFile = val;
-  }
+  void __set_outputFile(const std::string& val);
 
-  void __set_type(const CompactionType::type val) {
-    type = val;
-  }
+  void __set_type(const CompactionType::type val);
 
-  void __set_reason(const CompactionReason::type val) {
-    reason = val;
-  }
+  void __set_reason(const CompactionReason::type val);
 
-  void __set_localityGroup(const std::string& val) {
-    localityGroup = val;
-  }
+  void __set_localityGroup(const std::string& val);
 
-  void __set_entriesRead(const int64_t val) {
-    entriesRead = val;
-  }
+  void __set_entriesRead(const int64_t val);
 
-  void __set_entriesWritten(const int64_t val) {
-    entriesWritten = val;
-  }
+  void __set_entriesWritten(const int64_t val);
 
-  void __set_iterators(const std::vector<IteratorSetting> & val) {
-    iterators = val;
-  }
+  void __set_iterators(const std::vector<IteratorSetting> & val);
 
   bool operator == (const ActiveCompaction & rhs) const
   {
@@ -1477,30 +1462,35 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(ActiveCompaction &a, ActiveCompaction &b);
 
+inline std::ostream& operator<<(std::ostream& out, const ActiveCompaction& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _WriterOptions__isset {
   _WriterOptions__isset() : maxMemory(false), latencyMs(false), timeoutMs(false), threads(false), durability(false) {}
-  bool maxMemory;
-  bool latencyMs;
-  bool timeoutMs;
-  bool threads;
-  bool durability;
+  bool maxMemory :1;
+  bool latencyMs :1;
+  bool timeoutMs :1;
+  bool threads :1;
+  bool durability :1;
 } _WriterOptions__isset;
 
 class WriterOptions {
  public:
 
-  static const char* ascii_fingerprint; // = "6640C55D2C0D4C8C2E7589456EA0C61A";
-  static const uint8_t binary_fingerprint[16]; // = {0x66,0x40,0xC5,0x5D,0x2C,0x0D,0x4C,0x8C,0x2E,0x75,0x89,0x45,0x6E,0xA0,0xC6,0x1A};
-
+  WriterOptions(const WriterOptions&);
+  WriterOptions& operator=(const WriterOptions&);
   WriterOptions() : maxMemory(0), latencyMs(0), timeoutMs(0), threads(0), durability((Durability::type)0) {
   }
 
-  virtual ~WriterOptions() throw() {}
-
+  virtual ~WriterOptions() throw();
   int64_t maxMemory;
   int64_t latencyMs;
   int64_t timeoutMs;
@@ -1509,26 +1499,15 @@
 
   _WriterOptions__isset __isset;
 
-  void __set_maxMemory(const int64_t val) {
-    maxMemory = val;
-  }
+  void __set_maxMemory(const int64_t val);
 
-  void __set_latencyMs(const int64_t val) {
-    latencyMs = val;
-  }
+  void __set_latencyMs(const int64_t val);
 
-  void __set_timeoutMs(const int64_t val) {
-    timeoutMs = val;
-  }
+  void __set_timeoutMs(const int64_t val);
 
-  void __set_threads(const int32_t val) {
-    threads = val;
-  }
+  void __set_threads(const int32_t val);
 
-  void __set_durability(const Durability::type val) {
-    durability = val;
-    __isset.durability = true;
-  }
+  void __set_durability(const Durability::type val);
 
   bool operator == (const WriterOptions & rhs) const
   {
@@ -1555,39 +1534,40 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(WriterOptions &a, WriterOptions &b);
 
+inline std::ostream& operator<<(std::ostream& out, const WriterOptions& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _CompactionStrategyConfig__isset {
   _CompactionStrategyConfig__isset() : className(false), options(false) {}
-  bool className;
-  bool options;
+  bool className :1;
+  bool options :1;
 } _CompactionStrategyConfig__isset;
 
 class CompactionStrategyConfig {
  public:
 
-  static const char* ascii_fingerprint; // = "F7C641917C22B35AE581CCD54910B00D";
-  static const uint8_t binary_fingerprint[16]; // = {0xF7,0xC6,0x41,0x91,0x7C,0x22,0xB3,0x5A,0xE5,0x81,0xCC,0xD5,0x49,0x10,0xB0,0x0D};
-
+  CompactionStrategyConfig(const CompactionStrategyConfig&);
+  CompactionStrategyConfig& operator=(const CompactionStrategyConfig&);
   CompactionStrategyConfig() : className() {
   }
 
-  virtual ~CompactionStrategyConfig() throw() {}
-
+  virtual ~CompactionStrategyConfig() throw();
   std::string className;
   std::map<std::string, std::string>  options;
 
   _CompactionStrategyConfig__isset __isset;
 
-  void __set_className(const std::string& val) {
-    className = val;
-  }
+  void __set_className(const std::string& val);
 
-  void __set_options(const std::map<std::string, std::string> & val) {
-    options = val;
-  }
+  void __set_options(const std::map<std::string, std::string> & val);
 
   bool operator == (const CompactionStrategyConfig & rhs) const
   {
@@ -1606,33 +1586,36 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
 };
 
 void swap(CompactionStrategyConfig &a, CompactionStrategyConfig &b);
 
+inline std::ostream& operator<<(std::ostream& out, const CompactionStrategyConfig& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _UnknownScanner__isset {
   _UnknownScanner__isset() : msg(false) {}
-  bool msg;
+  bool msg :1;
 } _UnknownScanner__isset;
 
 class UnknownScanner : public ::apache::thrift::TException {
  public:
 
-  static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1";
-  static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
-
+  UnknownScanner(const UnknownScanner&);
+  UnknownScanner& operator=(const UnknownScanner&);
   UnknownScanner() : msg() {
   }
 
-  virtual ~UnknownScanner() throw() {}
-
+  virtual ~UnknownScanner() throw();
   std::string msg;
 
   _UnknownScanner__isset __isset;
 
-  void __set_msg(const std::string& val) {
-    msg = val;
-  }
+  void __set_msg(const std::string& val);
 
   bool operator == (const UnknownScanner & rhs) const
   {
@@ -1649,33 +1632,38 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
 };
 
 void swap(UnknownScanner &a, UnknownScanner &b);
 
+inline std::ostream& operator<<(std::ostream& out, const UnknownScanner& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _UnknownWriter__isset {
   _UnknownWriter__isset() : msg(false) {}
-  bool msg;
+  bool msg :1;
 } _UnknownWriter__isset;
 
 class UnknownWriter : public ::apache::thrift::TException {
  public:
 
-  static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1";
-  static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
-
+  UnknownWriter(const UnknownWriter&);
+  UnknownWriter& operator=(const UnknownWriter&);
   UnknownWriter() : msg() {
   }
 
-  virtual ~UnknownWriter() throw() {}
-
+  virtual ~UnknownWriter() throw();
   std::string msg;
 
   _UnknownWriter__isset __isset;
 
-  void __set_msg(const std::string& val) {
-    msg = val;
-  }
+  void __set_msg(const std::string& val);
 
   bool operator == (const UnknownWriter & rhs) const
   {
@@ -1692,33 +1680,38 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
 };
 
 void swap(UnknownWriter &a, UnknownWriter &b);
 
+inline std::ostream& operator<<(std::ostream& out, const UnknownWriter& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _NoMoreEntriesException__isset {
   _NoMoreEntriesException__isset() : msg(false) {}
-  bool msg;
+  bool msg :1;
 } _NoMoreEntriesException__isset;
 
 class NoMoreEntriesException : public ::apache::thrift::TException {
  public:
 
-  static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1";
-  static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
-
+  NoMoreEntriesException(const NoMoreEntriesException&);
+  NoMoreEntriesException& operator=(const NoMoreEntriesException&);
   NoMoreEntriesException() : msg() {
   }
 
-  virtual ~NoMoreEntriesException() throw() {}
-
+  virtual ~NoMoreEntriesException() throw();
   std::string msg;
 
   _NoMoreEntriesException__isset __isset;
 
-  void __set_msg(const std::string& val) {
-    msg = val;
-  }
+  void __set_msg(const std::string& val);
 
   bool operator == (const NoMoreEntriesException & rhs) const
   {
@@ -1735,33 +1728,38 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
 };
 
 void swap(NoMoreEntriesException &a, NoMoreEntriesException &b);
 
+inline std::ostream& operator<<(std::ostream& out, const NoMoreEntriesException& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _AccumuloException__isset {
   _AccumuloException__isset() : msg(false) {}
-  bool msg;
+  bool msg :1;
 } _AccumuloException__isset;
 
 class AccumuloException : public ::apache::thrift::TException {
  public:
 
-  static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1";
-  static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
-
+  AccumuloException(const AccumuloException&);
+  AccumuloException& operator=(const AccumuloException&);
   AccumuloException() : msg() {
   }
 
-  virtual ~AccumuloException() throw() {}
-
+  virtual ~AccumuloException() throw();
   std::string msg;
 
   _AccumuloException__isset __isset;
 
-  void __set_msg(const std::string& val) {
-    msg = val;
-  }
+  void __set_msg(const std::string& val);
 
   bool operator == (const AccumuloException & rhs) const
   {
@@ -1778,33 +1776,38 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
 };
 
 void swap(AccumuloException &a, AccumuloException &b);
 
+inline std::ostream& operator<<(std::ostream& out, const AccumuloException& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _AccumuloSecurityException__isset {
   _AccumuloSecurityException__isset() : msg(false) {}
-  bool msg;
+  bool msg :1;
 } _AccumuloSecurityException__isset;
 
 class AccumuloSecurityException : public ::apache::thrift::TException {
  public:
 
-  static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1";
-  static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
-
+  AccumuloSecurityException(const AccumuloSecurityException&);
+  AccumuloSecurityException& operator=(const AccumuloSecurityException&);
   AccumuloSecurityException() : msg() {
   }
 
-  virtual ~AccumuloSecurityException() throw() {}
-
+  virtual ~AccumuloSecurityException() throw();
   std::string msg;
 
   _AccumuloSecurityException__isset __isset;
 
-  void __set_msg(const std::string& val) {
-    msg = val;
-  }
+  void __set_msg(const std::string& val);
 
   bool operator == (const AccumuloSecurityException & rhs) const
   {
@@ -1821,33 +1824,38 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
 };
 
 void swap(AccumuloSecurityException &a, AccumuloSecurityException &b);
 
+inline std::ostream& operator<<(std::ostream& out, const AccumuloSecurityException& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _TableNotFoundException__isset {
   _TableNotFoundException__isset() : msg(false) {}
-  bool msg;
+  bool msg :1;
 } _TableNotFoundException__isset;
 
 class TableNotFoundException : public ::apache::thrift::TException {
  public:
 
-  static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1";
-  static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
-
+  TableNotFoundException(const TableNotFoundException&);
+  TableNotFoundException& operator=(const TableNotFoundException&);
   TableNotFoundException() : msg() {
   }
 
-  virtual ~TableNotFoundException() throw() {}
-
+  virtual ~TableNotFoundException() throw();
   std::string msg;
 
   _TableNotFoundException__isset __isset;
 
-  void __set_msg(const std::string& val) {
-    msg = val;
-  }
+  void __set_msg(const std::string& val);
 
   bool operator == (const TableNotFoundException & rhs) const
   {
@@ -1864,33 +1872,38 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
 };
 
 void swap(TableNotFoundException &a, TableNotFoundException &b);
 
+inline std::ostream& operator<<(std::ostream& out, const TableNotFoundException& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _TableExistsException__isset {
   _TableExistsException__isset() : msg(false) {}
-  bool msg;
+  bool msg :1;
 } _TableExistsException__isset;
 
 class TableExistsException : public ::apache::thrift::TException {
  public:
 
-  static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1";
-  static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
-
+  TableExistsException(const TableExistsException&);
+  TableExistsException& operator=(const TableExistsException&);
   TableExistsException() : msg() {
   }
 
-  virtual ~TableExistsException() throw() {}
-
+  virtual ~TableExistsException() throw();
   std::string msg;
 
   _TableExistsException__isset __isset;
 
-  void __set_msg(const std::string& val) {
-    msg = val;
-  }
+  void __set_msg(const std::string& val);
 
   bool operator == (const TableExistsException & rhs) const
   {
@@ -1907,33 +1920,38 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
 };
 
 void swap(TableExistsException &a, TableExistsException &b);
 
+inline std::ostream& operator<<(std::ostream& out, const TableExistsException& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 typedef struct _MutationsRejectedException__isset {
   _MutationsRejectedException__isset() : msg(false) {}
-  bool msg;
+  bool msg :1;
 } _MutationsRejectedException__isset;
 
 class MutationsRejectedException : public ::apache::thrift::TException {
  public:
 
-  static const char* ascii_fingerprint; // = "EFB929595D312AC8F305D5A794CFEDA1";
-  static const uint8_t binary_fingerprint[16]; // = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
-
+  MutationsRejectedException(const MutationsRejectedException&);
+  MutationsRejectedException& operator=(const MutationsRejectedException&);
   MutationsRejectedException() : msg() {
   }
 
-  virtual ~MutationsRejectedException() throw() {}
-
+  virtual ~MutationsRejectedException() throw();
   std::string msg;
 
   _MutationsRejectedException__isset __isset;
 
-  void __set_msg(const std::string& val) {
-    msg = val;
-  }
+  void __set_msg(const std::string& val);
 
   bool operator == (const MutationsRejectedException & rhs) const
   {
@@ -1950,10 +1968,163 @@
   uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
   uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
 
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
 };
 
 void swap(MutationsRejectedException &a, MutationsRejectedException &b);
 
+inline std::ostream& operator<<(std::ostream& out, const MutationsRejectedException& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
+typedef struct _NamespaceExistsException__isset {
+  _NamespaceExistsException__isset() : msg(false) {}
+  bool msg :1;
+} _NamespaceExistsException__isset;
+
+class NamespaceExistsException : public ::apache::thrift::TException {
+ public:
+
+  NamespaceExistsException(const NamespaceExistsException&);
+  NamespaceExistsException& operator=(const NamespaceExistsException&);
+  NamespaceExistsException() : msg() {
+  }
+
+  virtual ~NamespaceExistsException() throw();
+  std::string msg;
+
+  _NamespaceExistsException__isset __isset;
+
+  void __set_msg(const std::string& val);
+
+  bool operator == (const NamespaceExistsException & rhs) const
+  {
+    if (!(msg == rhs.msg))
+      return false;
+    return true;
+  }
+  bool operator != (const NamespaceExistsException &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const NamespaceExistsException & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
+};
+
+void swap(NamespaceExistsException &a, NamespaceExistsException &b);
+
+inline std::ostream& operator<<(std::ostream& out, const NamespaceExistsException& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
+typedef struct _NamespaceNotFoundException__isset {
+  _NamespaceNotFoundException__isset() : msg(false) {}
+  bool msg :1;
+} _NamespaceNotFoundException__isset;
+
+class NamespaceNotFoundException : public ::apache::thrift::TException {
+ public:
+
+  NamespaceNotFoundException(const NamespaceNotFoundException&);
+  NamespaceNotFoundException& operator=(const NamespaceNotFoundException&);
+  NamespaceNotFoundException() : msg() {
+  }
+
+  virtual ~NamespaceNotFoundException() throw();
+  std::string msg;
+
+  _NamespaceNotFoundException__isset __isset;
+
+  void __set_msg(const std::string& val);
+
+  bool operator == (const NamespaceNotFoundException & rhs) const
+  {
+    if (!(msg == rhs.msg))
+      return false;
+    return true;
+  }
+  bool operator != (const NamespaceNotFoundException &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const NamespaceNotFoundException & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
+};
+
+void swap(NamespaceNotFoundException &a, NamespaceNotFoundException &b);
+
+inline std::ostream& operator<<(std::ostream& out, const NamespaceNotFoundException& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
+typedef struct _NamespaceNotEmptyException__isset {
+  _NamespaceNotEmptyException__isset() : msg(false) {}
+  bool msg :1;
+} _NamespaceNotEmptyException__isset;
+
+class NamespaceNotEmptyException : public ::apache::thrift::TException {
+ public:
+
+  NamespaceNotEmptyException(const NamespaceNotEmptyException&);
+  NamespaceNotEmptyException& operator=(const NamespaceNotEmptyException&);
+  NamespaceNotEmptyException() : msg() {
+  }
+
+  virtual ~NamespaceNotEmptyException() throw();
+  std::string msg;
+
+  _NamespaceNotEmptyException__isset __isset;
+
+  void __set_msg(const std::string& val);
+
+  bool operator == (const NamespaceNotEmptyException & rhs) const
+  {
+    if (!(msg == rhs.msg))
+      return false;
+    return true;
+  }
+  bool operator != (const NamespaceNotEmptyException &rhs) const {
+    return !(*this == rhs);
+  }
+
+  bool operator < (const NamespaceNotEmptyException & ) const;
+
+  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
+  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
+
+  virtual void printTo(std::ostream& out) const;
+  mutable std::string thriftTExceptionMessageHolder_;
+  const char* what() const throw();
+};
+
+void swap(NamespaceNotEmptyException &a, NamespaceNotEmptyException &b);
+
+inline std::ostream& operator<<(std::ostream& out, const NamespaceNotEmptyException& obj)
+{
+  obj.printTo(out);
+  return out;
+}
+
 } // namespace
 
 #endif
diff --git a/src/main/java/org/apache/accumulo/proxy/Proxy.java b/src/main/java/org/apache/accumulo/proxy/Proxy.java
index 39cb28e..a3d185d 100644
--- a/src/main/java/org/apache/accumulo/proxy/Proxy.java
+++ b/src/main/java/org/apache/accumulo/proxy/Proxy.java
@@ -265,8 +265,8 @@
     TimedProcessor timedProcessor = new TimedProcessor(metricsFactory, processor, serverName, threadName);
 
     // Create the thrift server with our processor and properties
-    ServerAddress serverAddr = TServerUtils.startTServer(address, serverType, timedProcessor, protocolFactory, serverName, threadName, numThreads,
-        simpleTimerThreadpoolSize, threadpoolResizeInterval, maxFrameSize, sslParams, saslParams, serverSocketTimeout);
+    ServerAddress serverAddr = TServerUtils.startTServer(serverType, timedProcessor, protocolFactory, serverName, threadName, numThreads,
+        simpleTimerThreadpoolSize, threadpoolResizeInterval, maxFrameSize, sslParams, saslParams, serverSocketTimeout, address);
 
     return serverAddr;
   }
diff --git a/src/main/java/org/apache/accumulo/proxy/ProxyServer.java b/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
index f4310e8..a62e1a1 100644
--- a/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
+++ b/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
@@ -26,6 +26,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -49,6 +50,9 @@
 import org.apache.accumulo.core.client.Instance;
 import org.apache.accumulo.core.client.IteratorSetting;
 import org.apache.accumulo.core.client.MutationsRejectedException;
+import org.apache.accumulo.core.client.NamespaceExistsException;
+import org.apache.accumulo.core.client.NamespaceNotEmptyException;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
 import org.apache.accumulo.core.client.Scanner;
 import org.apache.accumulo.core.client.ScannerBase;
 import org.apache.accumulo.core.client.TableExistsException;
@@ -60,9 +64,9 @@
 import org.apache.accumulo.core.client.admin.NewTableConfiguration;
 import org.apache.accumulo.core.client.admin.TimeType;
 import org.apache.accumulo.core.client.impl.Credentials;
+import org.apache.accumulo.core.client.impl.Namespaces;
 import org.apache.accumulo.core.client.impl.thrift.TableOperationExceptionType;
 import org.apache.accumulo.core.client.impl.thrift.ThriftTableOperationException;
-import org.apache.accumulo.core.client.mock.MockInstance;
 import org.apache.accumulo.core.client.security.SecurityErrorCode;
 import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
 import org.apache.accumulo.core.client.security.tokens.PasswordToken;
@@ -77,9 +81,11 @@
 import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.security.NamespacePermission;
 import org.apache.accumulo.core.security.SystemPermission;
 import org.apache.accumulo.core.security.TablePermission;
 import org.apache.accumulo.core.util.ByteBufferUtil;
+import org.apache.accumulo.core.util.DeprecationUtil;
 import org.apache.accumulo.core.util.TextUtil;
 import org.apache.accumulo.proxy.thrift.AccumuloProxy;
 import org.apache.accumulo.proxy.thrift.BatchScanOptions;
@@ -186,7 +192,7 @@
 
     String useMock = props.getProperty("useMockInstance");
     if (useMock != null && Boolean.parseBoolean(useMock))
-      instance = new MockInstance();
+      instance = DeprecationUtil.makeMockInstance(this.getClass().getName());
     else {
       ClientConfiguration clientConf;
       if (props.containsKey("clientConfigurationFile")) {
@@ -309,6 +315,25 @@
     }
   }
 
+  private void handleExceptionNNF(Exception ex) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      throw ex;
+    } catch (AccumuloException e) {
+      Throwable cause = e.getCause();
+      if (null != cause && NamespaceNotFoundException.class.equals(cause.getClass())) {
+        throw new org.apache.accumulo.proxy.thrift.NamespaceNotFoundException(cause.toString());
+      }
+      handleAccumuloException(e);
+    } catch (AccumuloSecurityException e) {
+      handleAccumuloSecurityException(e);
+    } catch (NamespaceNotFoundException e) {
+      throw new org.apache.accumulo.proxy.thrift.NamespaceNotFoundException(ex.toString());
+    } catch (Exception e) {
+      throw new org.apache.accumulo.proxy.thrift.AccumuloException(e.toString());
+    }
+  }
+
   private void handleException(Exception ex) throws org.apache.accumulo.proxy.thrift.AccumuloException,
       org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
     try {
@@ -977,6 +1002,38 @@
     }
   }
 
+  @Override
+  public void grantNamespacePermission(ByteBuffer login, String user, String namespaceName, org.apache.accumulo.proxy.thrift.NamespacePermission perm)
+      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
+    try {
+      getConnector(login).securityOperations().grantNamespacePermission(user, namespaceName, NamespacePermission.getPermissionById((byte) perm.getValue()));
+    } catch (Exception e) {
+      handleException(e);
+    }
+  }
+
+  @Override
+  public boolean hasNamespacePermission(ByteBuffer login, String user, String namespaceName, org.apache.accumulo.proxy.thrift.NamespacePermission perm)
+      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
+    try {
+      return getConnector(login).securityOperations()
+          .hasNamespacePermission(user, namespaceName, NamespacePermission.getPermissionById((byte) perm.getValue()));
+    } catch (Exception e) {
+      handleException(e);
+      return false;
+    }
+  }
+
+  @Override
+  public void revokeNamespacePermission(ByteBuffer login, String user, String namespaceName, org.apache.accumulo.proxy.thrift.NamespacePermission perm)
+      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
+    try {
+      getConnector(login).securityOperations().revokeNamespacePermission(user, namespaceName, NamespacePermission.getPermissionById((byte) perm.getValue()));
+    } catch (Exception e) {
+      handleException(e);
+    }
+  }
+
   private Authorizations getAuthorizations(Set<ByteBuffer> authorizations) {
     List<String> auths = new ArrayList<>();
     for (ByteBuffer bbauth : authorizations) {
@@ -1549,6 +1606,238 @@
   }
 
   @Override
+  public String systemNamespace() throws TException {
+    return Namespaces.ACCUMULO_NAMESPACE;
+  }
+
+  @Override
+  public String defaultNamespace() throws TException {
+    return Namespaces.DEFAULT_NAMESPACE;
+  }
+
+  @Override
+  public List<String> listNamespaces(ByteBuffer login) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
+    try {
+      return new LinkedList<>(getConnector(login).namespaceOperations().list());
+    } catch (Exception e) {
+      handleException(e);
+      return null;
+    }
+  }
+
+  @Override
+  public boolean namespaceExists(ByteBuffer login, String namespaceName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
+    try {
+      return getConnector(login).namespaceOperations().exists(namespaceName);
+    } catch (Exception e) {
+      handleException(e);
+      return false;
+    }
+  }
+
+  @Override
+  public void createNamespace(ByteBuffer login, String namespaceName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceExistsException, TException {
+    try {
+      getConnector(login).namespaceOperations().create(namespaceName);
+    } catch (NamespaceExistsException e) {
+      throw new org.apache.accumulo.proxy.thrift.NamespaceExistsException(e.toString());
+    } catch (Exception e) {
+      handleException(e);
+    }
+  }
+
+  @Override
+  public void deleteNamespace(ByteBuffer login, String namespaceName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceNotFoundException,
+      org.apache.accumulo.proxy.thrift.NamespaceNotEmptyException, TException {
+    try {
+      getConnector(login).namespaceOperations().delete(namespaceName);
+    } catch (NamespaceNotFoundException e) {
+      throw new org.apache.accumulo.proxy.thrift.NamespaceNotFoundException(e.toString());
+    } catch (NamespaceNotEmptyException e) {
+      throw new org.apache.accumulo.proxy.thrift.NamespaceNotEmptyException(e.toString());
+    } catch (Exception e) {
+      handleException(e);
+    }
+  }
+
+  @Override
+  public void renameNamespace(ByteBuffer login, String oldNamespaceName, String newNamespaceName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceNotFoundException,
+      org.apache.accumulo.proxy.thrift.NamespaceExistsException, TException {
+    try {
+      getConnector(login).namespaceOperations().rename(oldNamespaceName, newNamespaceName);
+    } catch (NamespaceNotFoundException e) {
+      throw new org.apache.accumulo.proxy.thrift.NamespaceNotFoundException(e.toString());
+    } catch (NamespaceExistsException e) {
+      throw new org.apache.accumulo.proxy.thrift.NamespaceExistsException(e.toString());
+    } catch (Exception e) {
+      handleException(e);
+    }
+  }
+
+  @Override
+  public void setNamespaceProperty(ByteBuffer login, String namespaceName, String property, String value)
+      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
+      org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      getConnector(login).namespaceOperations().setProperty(namespaceName, property, value);
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+    }
+  }
+
+  @Override
+  public void removeNamespaceProperty(ByteBuffer login, String namespaceName, String property) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      getConnector(login).namespaceOperations().removeProperty(namespaceName, property);
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+    }
+  }
+
+  @Override
+  public Map<String,String> getNamespaceProperties(ByteBuffer login, String namespaceName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      Map<String,String> props = new HashMap<>();
+      for (Map.Entry<String,String> entry : getConnector(login).namespaceOperations().getProperties(namespaceName)) {
+        props.put(entry.getKey(), entry.getValue());
+      }
+      return props;
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+      return null;
+    }
+  }
+
+  @Override
+  public Map<String,String> namespaceIdMap(ByteBuffer login) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
+    try {
+      return getConnector(login).namespaceOperations().namespaceIdMap();
+    } catch (Exception e) {
+      handleException(e);
+      return null;
+    }
+  }
+
+  @Override
+  public void attachNamespaceIterator(ByteBuffer login, String namespaceName, org.apache.accumulo.proxy.thrift.IteratorSetting setting,
+      Set<org.apache.accumulo.proxy.thrift.IteratorScope> scopes) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      if (null != scopes && scopes.size() > 0) {
+        getConnector(login).namespaceOperations().attachIterator(namespaceName, getIteratorSetting(setting), getIteratorScopes(scopes));
+      } else {
+        getConnector(login).namespaceOperations().attachIterator(namespaceName, getIteratorSetting(setting));
+      }
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+    }
+  }
+
+  @Override
+  public void removeNamespaceIterator(ByteBuffer login, String namespaceName, String name, Set<org.apache.accumulo.proxy.thrift.IteratorScope> scopes)
+      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
+      org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      getConnector(login).namespaceOperations().removeIterator(namespaceName, name, getIteratorScopes(scopes));
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+    }
+  }
+
+  @Override
+  public org.apache.accumulo.proxy.thrift.IteratorSetting getNamespaceIteratorSetting(ByteBuffer login, String namespaceName, String name,
+      org.apache.accumulo.proxy.thrift.IteratorScope scope) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      IteratorSetting setting = getConnector(login).namespaceOperations().getIteratorSetting(namespaceName, name, getIteratorScope(scope));
+      return new org.apache.accumulo.proxy.thrift.IteratorSetting(setting.getPriority(), setting.getName(), setting.getIteratorClass(), setting.getOptions());
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+      return null;
+    }
+  }
+
+  @Override
+  public Map<String,Set<org.apache.accumulo.proxy.thrift.IteratorScope>> listNamespaceIterators(ByteBuffer login, String namespaceName)
+      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
+      org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      Map<String,Set<org.apache.accumulo.proxy.thrift.IteratorScope>> namespaceIters = new HashMap<>();
+      for (Map.Entry<String,EnumSet<IteratorScope>> entry : getConnector(login).namespaceOperations().listIterators(namespaceName).entrySet()) {
+        namespaceIters.put(entry.getKey(), getProxyIteratorScopes(entry.getValue()));
+      }
+      return namespaceIters;
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+      return null;
+    }
+  }
+
+  @Override
+  public void checkNamespaceIteratorConflicts(ByteBuffer login, String namespaceName, org.apache.accumulo.proxy.thrift.IteratorSetting setting,
+      Set<org.apache.accumulo.proxy.thrift.IteratorScope> scopes) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      getConnector(login).namespaceOperations().checkIteratorConflicts(namespaceName, getIteratorSetting(setting), getIteratorScopes(scopes));
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+    }
+  }
+
+  @Override
+  public int addNamespaceConstraint(ByteBuffer login, String namespaceName, String constraintClassName)
+      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
+      org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      return getConnector(login).namespaceOperations().addConstraint(namespaceName, constraintClassName);
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+      return -1;
+    }
+  }
+
+  @Override
+  public void removeNamespaceConstraint(ByteBuffer login, String namespaceName, int id) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      getConnector(login).namespaceOperations().removeConstraint(namespaceName, id);
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+    }
+  }
+
+  @Override
+  public Map<String,Integer> listNamespaceConstraints(ByteBuffer login, String namespaceName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
+      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      return getConnector(login).namespaceOperations().listConstraints(namespaceName);
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+      return null;
+    }
+  }
+
+  @Override
+  public boolean testNamespaceClassLoad(ByteBuffer login, String namespaceName, String className, String asTypeName)
+      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
+      org.apache.accumulo.proxy.thrift.NamespaceNotFoundException, TException {
+    try {
+      return getConnector(login).namespaceOperations().testClassLoad(namespaceName, className, asTypeName);
+    } catch (Exception e) {
+      handleExceptionNNF(e);
+      return false;
+    }
+  }
+
+  @Override
   public void pingTabletServer(ByteBuffer login, String tserver) throws org.apache.accumulo.proxy.thrift.AccumuloException,
       org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
     try {
diff --git a/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java b/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java
deleted file mode 100644
index 9aeada0..0000000
--- a/src/main/java/org/apache/accumulo/proxy/TestProxyClient.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.accumulo.proxy;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.security.sasl.SaslException;
-
-import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.iterators.user.RegExFilter;
-import org.apache.accumulo.core.rpc.UGIAssumingTransport;
-import org.apache.accumulo.proxy.thrift.AccumuloProxy;
-import org.apache.accumulo.proxy.thrift.ColumnUpdate;
-import org.apache.accumulo.proxy.thrift.Key;
-import org.apache.accumulo.proxy.thrift.ScanResult;
-import org.apache.accumulo.proxy.thrift.TimeType;
-import org.apache.hadoop.security.UserGroupInformation;
-import org.apache.thrift.protocol.TCompactProtocol;
-import org.apache.thrift.protocol.TProtocol;
-import org.apache.thrift.protocol.TProtocolFactory;
-import org.apache.thrift.transport.TFramedTransport;
-import org.apache.thrift.transport.TSaslClientTransport;
-import org.apache.thrift.transport.TSocket;
-import org.apache.thrift.transport.TTransport;
-import org.apache.thrift.transport.TTransportException;
-
-public class TestProxyClient {
-
-  protected AccumuloProxy.Client proxy;
-  protected TTransport transport;
-
-  public TestProxyClient(String host, int port) throws TTransportException {
-    this(host, port, new TCompactProtocol.Factory());
-  }
-
-  public TestProxyClient(String host, int port, TProtocolFactory protoFactory) throws TTransportException {
-    final TSocket socket = new TSocket(host, port);
-    socket.setTimeout(600000);
-    transport = new TFramedTransport(socket);
-    final TProtocol protocol = protoFactory.getProtocol(transport);
-    proxy = new AccumuloProxy.Client(protocol);
-    transport.open();
-  }
-
-  public TestProxyClient(String host, int port, TProtocolFactory protoFactory, String proxyPrimary, UserGroupInformation ugi) throws SaslException,
-      TTransportException {
-    TSocket socket = new TSocket(host, port);
-    TSaslClientTransport saslTransport = new TSaslClientTransport("GSSAPI", null, proxyPrimary, host, Collections.singletonMap("javax.security.sasl.qop",
-        "auth"), null, socket);
-
-    transport = new UGIAssumingTransport(saslTransport, ugi);
-
-    // UGI transport will perform the doAs for us
-    transport.open();
-
-    AccumuloProxy.Client.Factory factory = new AccumuloProxy.Client.Factory();
-    final TProtocol protocol = protoFactory.getProtocol(transport);
-    proxy = factory.getClient(protocol);
-  }
-
-  public synchronized void close() {
-    if (null != transport) {
-      transport.close();
-      transport = null;
-    }
-  }
-
-  public AccumuloProxy.Client proxy() {
-    return proxy;
-  }
-
-  public static void main(String[] args) throws Exception {
-
-    TestProxyClient tpc = new TestProxyClient("localhost", 42424);
-    String principal = "root";
-    Map<String,String> props = new TreeMap<>();
-    props.put("password", "secret");
-
-    System.out.println("Logging in");
-    ByteBuffer login = tpc.proxy.login(principal, props);
-
-    System.out.println("Creating user: ");
-    if (!tpc.proxy().listLocalUsers(login).contains("testuser")) {
-      tpc.proxy().createLocalUser(login, "testuser", ByteBuffer.wrap("testpass".getBytes(UTF_8)));
-    }
-    System.out.println("UserList: " + tpc.proxy().listLocalUsers(login));
-
-    System.out.println("Listing: " + tpc.proxy().listTables(login));
-
-    System.out.println("Deleting: ");
-    String testTable = "testtableOMGOMGOMG";
-
-    System.out.println("Creating: ");
-
-    if (tpc.proxy().tableExists(login, testTable))
-      tpc.proxy().deleteTable(login, testTable);
-
-    tpc.proxy().createTable(login, testTable, true, TimeType.MILLIS);
-
-    System.out.println("Listing: " + tpc.proxy().listTables(login));
-
-    System.out.println("Writing: ");
-    Date start = new Date();
-    Date then = new Date();
-    int maxInserts = 1000000;
-    String format = "%1$05d";
-    Map<ByteBuffer,List<ColumnUpdate>> mutations = new HashMap<>();
-    for (int i = 0; i < maxInserts; i++) {
-      String result = String.format(format, i);
-      ColumnUpdate update = new ColumnUpdate(ByteBuffer.wrap(("cf" + i).getBytes(UTF_8)), ByteBuffer.wrap(("cq" + i).getBytes(UTF_8)));
-      update.setValue(Util.randStringBuffer(10));
-      mutations.put(ByteBuffer.wrap(result.getBytes(UTF_8)), Collections.singletonList(update));
-
-      if (i % 1000 == 0) {
-        tpc.proxy().updateAndFlush(login, testTable, mutations);
-        mutations.clear();
-      }
-    }
-    tpc.proxy().updateAndFlush(login, testTable, mutations);
-    Date end = new Date();
-    System.out.println(" End of writing: " + (end.getTime() - start.getTime()));
-
-    tpc.proxy().deleteTable(login, testTable);
-    tpc.proxy().createTable(login, testTable, true, TimeType.MILLIS);
-
-    // Thread.sleep(1000);
-
-    System.out.println("Writing async: ");
-    start = new Date();
-    then = new Date();
-    mutations.clear();
-    String writer = tpc.proxy().createWriter(login, testTable, null);
-    for (int i = 0; i < maxInserts; i++) {
-      String result = String.format(format, i);
-      Key pkey = new Key();
-      pkey.setRow(result.getBytes(UTF_8));
-      ColumnUpdate update = new ColumnUpdate(ByteBuffer.wrap(("cf" + i).getBytes(UTF_8)), ByteBuffer.wrap(("cq" + i).getBytes(UTF_8)));
-      update.setValue(Util.randStringBuffer(10));
-      mutations.put(ByteBuffer.wrap(result.getBytes(UTF_8)), Collections.singletonList(update));
-      tpc.proxy().update(writer, mutations);
-      mutations.clear();
-    }
-
-    end = new Date();
-    System.out.println(" End of writing: " + (end.getTime() - start.getTime()));
-    start = end;
-    System.out.println("Closing...");
-    tpc.proxy().closeWriter(writer);
-    end = new Date();
-    System.out.println(" End of closing: " + (end.getTime() - start.getTime()));
-
-    System.out.println("Reading: ");
-
-    String regex = "cf1.*";
-
-    IteratorSetting is = new IteratorSetting(50, regex, RegExFilter.class);
-    RegExFilter.setRegexs(is, null, regex, null, null, false);
-
-    String cookie = tpc.proxy().createScanner(login, testTable, null);
-
-    int i = 0;
-    start = new Date();
-    then = new Date();
-    boolean hasNext = true;
-
-    int k = 1000;
-    while (hasNext) {
-      ScanResult kvList = tpc.proxy().nextK(cookie, k);
-
-      Date now = new Date();
-      System.out.println(i + " " + (now.getTime() - then.getTime()));
-      then = now;
-
-      i += kvList.getResultsSize();
-      // for (TKeyValue kv:kvList.getResults()) System.out.println(new Key(kv.getKey()));
-      hasNext = kvList.isMore();
-    }
-    end = new Date();
-    System.out.println("Total entries: " + i + " total time " + (end.getTime() - start.getTime()));
-  }
-}
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloException.java b/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloException.java
index 724a92e..76dd4bc 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloException.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class AccumuloException extends TException implements org.apache.thrift.TBase<AccumuloException, AccumuloException._Fields>, java.io.Serializable, Cloneable, Comparable<AccumuloException> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class AccumuloException extends TException implements org.apache.thrift.TBase<AccumuloException, AccumuloException._Fields>, java.io.Serializable, Cloneable, Comparable<AccumuloException> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("AccumuloException");
 
   private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -243,7 +246,14 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloProxy.java b/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloProxy.java
index eaa49ef..150de3e 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloProxy.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloProxy.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class AccumuloProxy {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class AccumuloProxy {
 
   public interface Iface {
 
@@ -172,6 +175,12 @@
 
     public void revokeTablePermission(ByteBuffer login, String user, String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
+    public void grantNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+
+    public boolean hasNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+
+    public void revokeNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+
     public String createBatchScanner(ByteBuffer login, String tableName, BatchScanOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
     public String createScanner(ByteBuffer login, String tableName, ScanOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
@@ -206,6 +215,46 @@
 
     public Key getFollowing(Key key, PartialKey part) throws org.apache.thrift.TException;
 
+    public String systemNamespace() throws org.apache.thrift.TException;
+
+    public String defaultNamespace() throws org.apache.thrift.TException;
+
+    public List<String> listNamespaces(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+
+    public boolean namespaceExists(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+
+    public void createNamespace(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceExistsException, org.apache.thrift.TException;
+
+    public void deleteNamespace(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceNotEmptyException, org.apache.thrift.TException;
+
+    public void renameNamespace(ByteBuffer login, String oldNamespaceName, String newNamespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceExistsException, org.apache.thrift.TException;
+
+    public void setNamespaceProperty(ByteBuffer login, String namespaceName, String property, String value) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public void removeNamespaceProperty(ByteBuffer login, String namespaceName, String property) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public Map<String,String> getNamespaceProperties(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public Map<String,String> namespaceIdMap(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+
+    public void attachNamespaceIterator(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public void removeNamespaceIterator(ByteBuffer login, String namespaceName, String name, Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public IteratorSetting getNamespaceIteratorSetting(ByteBuffer login, String namespaceName, String name, IteratorScope scope) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public Map<String,Set<IteratorScope>> listNamespaceIterators(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public void checkNamespaceIteratorConflicts(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public int addNamespaceConstraint(ByteBuffer login, String namespaceName, String constraintClassName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public void removeNamespaceConstraint(ByteBuffer login, String namespaceName, int id) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public Map<String,Integer> listNamespaceConstraints(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
+    public boolean testNamespaceClassLoad(ByteBuffer login, String namespaceName, String className, String asTypeName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
+
   }
 
   public interface AsyncIface {
@@ -330,6 +379,12 @@
 
     public void revokeTablePermission(ByteBuffer login, String user, String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
 
+    public void grantNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void hasNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void revokeNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
     public void createBatchScanner(ByteBuffer login, String tableName, BatchScanOptions options, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
 
     public void createScanner(ByteBuffer login, String tableName, ScanOptions options, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
@@ -364,6 +419,46 @@
 
     public void getFollowing(Key key, PartialKey part, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
 
+    public void systemNamespace(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void defaultNamespace(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void listNamespaces(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void namespaceExists(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void createNamespace(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void deleteNamespace(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void renameNamespace(ByteBuffer login, String oldNamespaceName, String newNamespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void setNamespaceProperty(ByteBuffer login, String namespaceName, String property, String value, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void removeNamespaceProperty(ByteBuffer login, String namespaceName, String property, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void getNamespaceProperties(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void namespaceIdMap(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void attachNamespaceIterator(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void removeNamespaceIterator(ByteBuffer login, String namespaceName, String name, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void getNamespaceIteratorSetting(ByteBuffer login, String namespaceName, String name, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void listNamespaceIterators(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void checkNamespaceIteratorConflicts(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void addNamespaceConstraint(ByteBuffer login, String namespaceName, String constraintClassName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void removeNamespaceConstraint(ByteBuffer login, String namespaceName, int id, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void listNamespaceConstraints(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
+    public void testNamespaceClassLoad(ByteBuffer login, String namespaceName, String className, String asTypeName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+
   }
 
   public static class Client extends org.apache.thrift.TServiceClient implements Iface {
@@ -2232,6 +2327,96 @@
       return;
     }
 
+    public void grantNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      send_grantNamespacePermission(login, user, namespaceName, perm);
+      recv_grantNamespacePermission();
+    }
+
+    public void send_grantNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws org.apache.thrift.TException
+    {
+      grantNamespacePermission_args args = new grantNamespacePermission_args();
+      args.setLogin(login);
+      args.setUser(user);
+      args.setNamespaceName(namespaceName);
+      args.setPerm(perm);
+      sendBase("grantNamespacePermission", args);
+    }
+
+    public void recv_grantNamespacePermission() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      grantNamespacePermission_result result = new grantNamespacePermission_result();
+      receiveBase(result, "grantNamespacePermission");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      return;
+    }
+
+    public boolean hasNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      send_hasNamespacePermission(login, user, namespaceName, perm);
+      return recv_hasNamespacePermission();
+    }
+
+    public void send_hasNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws org.apache.thrift.TException
+    {
+      hasNamespacePermission_args args = new hasNamespacePermission_args();
+      args.setLogin(login);
+      args.setUser(user);
+      args.setNamespaceName(namespaceName);
+      args.setPerm(perm);
+      sendBase("hasNamespacePermission", args);
+    }
+
+    public boolean recv_hasNamespacePermission() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      hasNamespacePermission_result result = new hasNamespacePermission_result();
+      receiveBase(result, "hasNamespacePermission");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "hasNamespacePermission failed: unknown result");
+    }
+
+    public void revokeNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      send_revokeNamespacePermission(login, user, namespaceName, perm);
+      recv_revokeNamespacePermission();
+    }
+
+    public void send_revokeNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws org.apache.thrift.TException
+    {
+      revokeNamespacePermission_args args = new revokeNamespacePermission_args();
+      args.setLogin(login);
+      args.setUser(user);
+      args.setNamespaceName(namespaceName);
+      args.setPerm(perm);
+      sendBase("revokeNamespacePermission", args);
+    }
+
+    public void recv_revokeNamespacePermission() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      revokeNamespacePermission_result result = new revokeNamespacePermission_result();
+      receiveBase(result, "revokeNamespacePermission");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      return;
+    }
+
     public String createBatchScanner(ByteBuffer login, String tableName, BatchScanOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_createBatchScanner(login, tableName, options);
@@ -2492,7 +2677,7 @@
       update_args args = new update_args();
       args.setWriter(writer);
       args.setCells(cells);
-      sendBase("update", args);
+      sendBaseOneway("update", args);
     }
 
     public void flush(String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException
@@ -2716,6 +2901,628 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getFollowing failed: unknown result");
     }
 
+    public String systemNamespace() throws org.apache.thrift.TException
+    {
+      send_systemNamespace();
+      return recv_systemNamespace();
+    }
+
+    public void send_systemNamespace() throws org.apache.thrift.TException
+    {
+      systemNamespace_args args = new systemNamespace_args();
+      sendBase("systemNamespace", args);
+    }
+
+    public String recv_systemNamespace() throws org.apache.thrift.TException
+    {
+      systemNamespace_result result = new systemNamespace_result();
+      receiveBase(result, "systemNamespace");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "systemNamespace failed: unknown result");
+    }
+
+    public String defaultNamespace() throws org.apache.thrift.TException
+    {
+      send_defaultNamespace();
+      return recv_defaultNamespace();
+    }
+
+    public void send_defaultNamespace() throws org.apache.thrift.TException
+    {
+      defaultNamespace_args args = new defaultNamespace_args();
+      sendBase("defaultNamespace", args);
+    }
+
+    public String recv_defaultNamespace() throws org.apache.thrift.TException
+    {
+      defaultNamespace_result result = new defaultNamespace_result();
+      receiveBase(result, "defaultNamespace");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "defaultNamespace failed: unknown result");
+    }
+
+    public List<String> listNamespaces(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      send_listNamespaces(login);
+      return recv_listNamespaces();
+    }
+
+    public void send_listNamespaces(ByteBuffer login) throws org.apache.thrift.TException
+    {
+      listNamespaces_args args = new listNamespaces_args();
+      args.setLogin(login);
+      sendBase("listNamespaces", args);
+    }
+
+    public List<String> recv_listNamespaces() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      listNamespaces_result result = new listNamespaces_result();
+      receiveBase(result, "listNamespaces");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listNamespaces failed: unknown result");
+    }
+
+    public boolean namespaceExists(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      send_namespaceExists(login, namespaceName);
+      return recv_namespaceExists();
+    }
+
+    public void send_namespaceExists(ByteBuffer login, String namespaceName) throws org.apache.thrift.TException
+    {
+      namespaceExists_args args = new namespaceExists_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      sendBase("namespaceExists", args);
+    }
+
+    public boolean recv_namespaceExists() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      namespaceExists_result result = new namespaceExists_result();
+      receiveBase(result, "namespaceExists");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "namespaceExists failed: unknown result");
+    }
+
+    public void createNamespace(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceExistsException, org.apache.thrift.TException
+    {
+      send_createNamespace(login, namespaceName);
+      recv_createNamespace();
+    }
+
+    public void send_createNamespace(ByteBuffer login, String namespaceName) throws org.apache.thrift.TException
+    {
+      createNamespace_args args = new createNamespace_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      sendBase("createNamespace", args);
+    }
+
+    public void recv_createNamespace() throws AccumuloException, AccumuloSecurityException, NamespaceExistsException, org.apache.thrift.TException
+    {
+      createNamespace_result result = new createNamespace_result();
+      receiveBase(result, "createNamespace");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      return;
+    }
+
+    public void deleteNamespace(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceNotEmptyException, org.apache.thrift.TException
+    {
+      send_deleteNamespace(login, namespaceName);
+      recv_deleteNamespace();
+    }
+
+    public void send_deleteNamespace(ByteBuffer login, String namespaceName) throws org.apache.thrift.TException
+    {
+      deleteNamespace_args args = new deleteNamespace_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      sendBase("deleteNamespace", args);
+    }
+
+    public void recv_deleteNamespace() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceNotEmptyException, org.apache.thrift.TException
+    {
+      deleteNamespace_result result = new deleteNamespace_result();
+      receiveBase(result, "deleteNamespace");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      if (result.ouch4 != null) {
+        throw result.ouch4;
+      }
+      return;
+    }
+
+    public void renameNamespace(ByteBuffer login, String oldNamespaceName, String newNamespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceExistsException, org.apache.thrift.TException
+    {
+      send_renameNamespace(login, oldNamespaceName, newNamespaceName);
+      recv_renameNamespace();
+    }
+
+    public void send_renameNamespace(ByteBuffer login, String oldNamespaceName, String newNamespaceName) throws org.apache.thrift.TException
+    {
+      renameNamespace_args args = new renameNamespace_args();
+      args.setLogin(login);
+      args.setOldNamespaceName(oldNamespaceName);
+      args.setNewNamespaceName(newNamespaceName);
+      sendBase("renameNamespace", args);
+    }
+
+    public void recv_renameNamespace() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceExistsException, org.apache.thrift.TException
+    {
+      renameNamespace_result result = new renameNamespace_result();
+      receiveBase(result, "renameNamespace");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      if (result.ouch4 != null) {
+        throw result.ouch4;
+      }
+      return;
+    }
+
+    public void setNamespaceProperty(ByteBuffer login, String namespaceName, String property, String value) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_setNamespaceProperty(login, namespaceName, property, value);
+      recv_setNamespaceProperty();
+    }
+
+    public void send_setNamespaceProperty(ByteBuffer login, String namespaceName, String property, String value) throws org.apache.thrift.TException
+    {
+      setNamespaceProperty_args args = new setNamespaceProperty_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      args.setProperty(property);
+      args.setValue(value);
+      sendBase("setNamespaceProperty", args);
+    }
+
+    public void recv_setNamespaceProperty() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      setNamespaceProperty_result result = new setNamespaceProperty_result();
+      receiveBase(result, "setNamespaceProperty");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      return;
+    }
+
+    public void removeNamespaceProperty(ByteBuffer login, String namespaceName, String property) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_removeNamespaceProperty(login, namespaceName, property);
+      recv_removeNamespaceProperty();
+    }
+
+    public void send_removeNamespaceProperty(ByteBuffer login, String namespaceName, String property) throws org.apache.thrift.TException
+    {
+      removeNamespaceProperty_args args = new removeNamespaceProperty_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      args.setProperty(property);
+      sendBase("removeNamespaceProperty", args);
+    }
+
+    public void recv_removeNamespaceProperty() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      removeNamespaceProperty_result result = new removeNamespaceProperty_result();
+      receiveBase(result, "removeNamespaceProperty");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      return;
+    }
+
+    public Map<String,String> getNamespaceProperties(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_getNamespaceProperties(login, namespaceName);
+      return recv_getNamespaceProperties();
+    }
+
+    public void send_getNamespaceProperties(ByteBuffer login, String namespaceName) throws org.apache.thrift.TException
+    {
+      getNamespaceProperties_args args = new getNamespaceProperties_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      sendBase("getNamespaceProperties", args);
+    }
+
+    public Map<String,String> recv_getNamespaceProperties() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      getNamespaceProperties_result result = new getNamespaceProperties_result();
+      receiveBase(result, "getNamespaceProperties");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getNamespaceProperties failed: unknown result");
+    }
+
+    public Map<String,String> namespaceIdMap(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      send_namespaceIdMap(login);
+      return recv_namespaceIdMap();
+    }
+
+    public void send_namespaceIdMap(ByteBuffer login) throws org.apache.thrift.TException
+    {
+      namespaceIdMap_args args = new namespaceIdMap_args();
+      args.setLogin(login);
+      sendBase("namespaceIdMap", args);
+    }
+
+    public Map<String,String> recv_namespaceIdMap() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    {
+      namespaceIdMap_result result = new namespaceIdMap_result();
+      receiveBase(result, "namespaceIdMap");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "namespaceIdMap failed: unknown result");
+    }
+
+    public void attachNamespaceIterator(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_attachNamespaceIterator(login, namespaceName, setting, scopes);
+      recv_attachNamespaceIterator();
+    }
+
+    public void send_attachNamespaceIterator(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes) throws org.apache.thrift.TException
+    {
+      attachNamespaceIterator_args args = new attachNamespaceIterator_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      args.setSetting(setting);
+      args.setScopes(scopes);
+      sendBase("attachNamespaceIterator", args);
+    }
+
+    public void recv_attachNamespaceIterator() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      attachNamespaceIterator_result result = new attachNamespaceIterator_result();
+      receiveBase(result, "attachNamespaceIterator");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      return;
+    }
+
+    public void removeNamespaceIterator(ByteBuffer login, String namespaceName, String name, Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_removeNamespaceIterator(login, namespaceName, name, scopes);
+      recv_removeNamespaceIterator();
+    }
+
+    public void send_removeNamespaceIterator(ByteBuffer login, String namespaceName, String name, Set<IteratorScope> scopes) throws org.apache.thrift.TException
+    {
+      removeNamespaceIterator_args args = new removeNamespaceIterator_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      args.setName(name);
+      args.setScopes(scopes);
+      sendBase("removeNamespaceIterator", args);
+    }
+
+    public void recv_removeNamespaceIterator() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      removeNamespaceIterator_result result = new removeNamespaceIterator_result();
+      receiveBase(result, "removeNamespaceIterator");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      return;
+    }
+
+    public IteratorSetting getNamespaceIteratorSetting(ByteBuffer login, String namespaceName, String name, IteratorScope scope) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_getNamespaceIteratorSetting(login, namespaceName, name, scope);
+      return recv_getNamespaceIteratorSetting();
+    }
+
+    public void send_getNamespaceIteratorSetting(ByteBuffer login, String namespaceName, String name, IteratorScope scope) throws org.apache.thrift.TException
+    {
+      getNamespaceIteratorSetting_args args = new getNamespaceIteratorSetting_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      args.setName(name);
+      args.setScope(scope);
+      sendBase("getNamespaceIteratorSetting", args);
+    }
+
+    public IteratorSetting recv_getNamespaceIteratorSetting() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      getNamespaceIteratorSetting_result result = new getNamespaceIteratorSetting_result();
+      receiveBase(result, "getNamespaceIteratorSetting");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getNamespaceIteratorSetting failed: unknown result");
+    }
+
+    public Map<String,Set<IteratorScope>> listNamespaceIterators(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_listNamespaceIterators(login, namespaceName);
+      return recv_listNamespaceIterators();
+    }
+
+    public void send_listNamespaceIterators(ByteBuffer login, String namespaceName) throws org.apache.thrift.TException
+    {
+      listNamespaceIterators_args args = new listNamespaceIterators_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      sendBase("listNamespaceIterators", args);
+    }
+
+    public Map<String,Set<IteratorScope>> recv_listNamespaceIterators() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      listNamespaceIterators_result result = new listNamespaceIterators_result();
+      receiveBase(result, "listNamespaceIterators");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listNamespaceIterators failed: unknown result");
+    }
+
+    public void checkNamespaceIteratorConflicts(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes);
+      recv_checkNamespaceIteratorConflicts();
+    }
+
+    public void send_checkNamespaceIteratorConflicts(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes) throws org.apache.thrift.TException
+    {
+      checkNamespaceIteratorConflicts_args args = new checkNamespaceIteratorConflicts_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      args.setSetting(setting);
+      args.setScopes(scopes);
+      sendBase("checkNamespaceIteratorConflicts", args);
+    }
+
+    public void recv_checkNamespaceIteratorConflicts() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      checkNamespaceIteratorConflicts_result result = new checkNamespaceIteratorConflicts_result();
+      receiveBase(result, "checkNamespaceIteratorConflicts");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      return;
+    }
+
+    public int addNamespaceConstraint(ByteBuffer login, String namespaceName, String constraintClassName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_addNamespaceConstraint(login, namespaceName, constraintClassName);
+      return recv_addNamespaceConstraint();
+    }
+
+    public void send_addNamespaceConstraint(ByteBuffer login, String namespaceName, String constraintClassName) throws org.apache.thrift.TException
+    {
+      addNamespaceConstraint_args args = new addNamespaceConstraint_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      args.setConstraintClassName(constraintClassName);
+      sendBase("addNamespaceConstraint", args);
+    }
+
+    public int recv_addNamespaceConstraint() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      addNamespaceConstraint_result result = new addNamespaceConstraint_result();
+      receiveBase(result, "addNamespaceConstraint");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addNamespaceConstraint failed: unknown result");
+    }
+
+    public void removeNamespaceConstraint(ByteBuffer login, String namespaceName, int id) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_removeNamespaceConstraint(login, namespaceName, id);
+      recv_removeNamespaceConstraint();
+    }
+
+    public void send_removeNamespaceConstraint(ByteBuffer login, String namespaceName, int id) throws org.apache.thrift.TException
+    {
+      removeNamespaceConstraint_args args = new removeNamespaceConstraint_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      args.setId(id);
+      sendBase("removeNamespaceConstraint", args);
+    }
+
+    public void recv_removeNamespaceConstraint() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      removeNamespaceConstraint_result result = new removeNamespaceConstraint_result();
+      receiveBase(result, "removeNamespaceConstraint");
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      return;
+    }
+
+    public Map<String,Integer> listNamespaceConstraints(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_listNamespaceConstraints(login, namespaceName);
+      return recv_listNamespaceConstraints();
+    }
+
+    public void send_listNamespaceConstraints(ByteBuffer login, String namespaceName) throws org.apache.thrift.TException
+    {
+      listNamespaceConstraints_args args = new listNamespaceConstraints_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      sendBase("listNamespaceConstraints", args);
+    }
+
+    public Map<String,Integer> recv_listNamespaceConstraints() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      listNamespaceConstraints_result result = new listNamespaceConstraints_result();
+      receiveBase(result, "listNamespaceConstraints");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listNamespaceConstraints failed: unknown result");
+    }
+
+    public boolean testNamespaceClassLoad(ByteBuffer login, String namespaceName, String className, String asTypeName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      send_testNamespaceClassLoad(login, namespaceName, className, asTypeName);
+      return recv_testNamespaceClassLoad();
+    }
+
+    public void send_testNamespaceClassLoad(ByteBuffer login, String namespaceName, String className, String asTypeName) throws org.apache.thrift.TException
+    {
+      testNamespaceClassLoad_args args = new testNamespaceClassLoad_args();
+      args.setLogin(login);
+      args.setNamespaceName(namespaceName);
+      args.setClassName(className);
+      args.setAsTypeName(asTypeName);
+      sendBase("testNamespaceClassLoad", args);
+    }
+
+    public boolean recv_testNamespaceClassLoad() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    {
+      testNamespaceClassLoad_result result = new testNamespaceClassLoad_result();
+      receiveBase(result, "testNamespaceClassLoad");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch1 != null) {
+        throw result.ouch1;
+      }
+      if (result.ouch2 != null) {
+        throw result.ouch2;
+      }
+      if (result.ouch3 != null) {
+        throw result.ouch3;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "testNamespaceClassLoad failed: unknown result");
+    }
+
   }
   public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
     public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
@@ -5017,6 +5824,129 @@
       }
     }
 
+    public void grantNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      grantNamespacePermission_call method_call = new grantNamespacePermission_call(login, user, namespaceName, perm, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class grantNamespacePermission_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String user;
+      private String namespaceName;
+      private NamespacePermission perm;
+      public grantNamespacePermission_call(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.user = user;
+        this.namespaceName = namespaceName;
+        this.perm = perm;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("grantNamespacePermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        grantNamespacePermission_args args = new grantNamespacePermission_args();
+        args.setLogin(login);
+        args.setUser(user);
+        args.setNamespaceName(namespaceName);
+        args.setPerm(perm);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_grantNamespacePermission();
+      }
+    }
+
+    public void hasNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      hasNamespacePermission_call method_call = new hasNamespacePermission_call(login, user, namespaceName, perm, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class hasNamespacePermission_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String user;
+      private String namespaceName;
+      private NamespacePermission perm;
+      public hasNamespacePermission_call(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.user = user;
+        this.namespaceName = namespaceName;
+        this.perm = perm;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("hasNamespacePermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        hasNamespacePermission_args args = new hasNamespacePermission_args();
+        args.setLogin(login);
+        args.setUser(user);
+        args.setNamespaceName(namespaceName);
+        args.setPerm(perm);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_hasNamespacePermission();
+      }
+    }
+
+    public void revokeNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      revokeNamespacePermission_call method_call = new revokeNamespacePermission_call(login, user, namespaceName, perm, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class revokeNamespacePermission_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String user;
+      private String namespaceName;
+      private NamespacePermission perm;
+      public revokeNamespacePermission_call(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.user = user;
+        this.namespaceName = namespaceName;
+        this.perm = perm;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("revokeNamespacePermission", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        revokeNamespacePermission_args args = new revokeNamespacePermission_args();
+        args.setLogin(login);
+        args.setUser(user);
+        args.setNamespaceName(namespaceName);
+        args.setPerm(perm);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_revokeNamespacePermission();
+      }
+    }
+
     public void createBatchScanner(ByteBuffer login, String tableName, BatchScanOptions options, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
       checkReady();
       createBatchScanner_call method_call = new createBatchScanner_call(login, tableName, options, resultHandler, this, ___protocolFactory, ___transport);
@@ -5317,7 +6247,7 @@
       }
 
       public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
-        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("update", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("update", org.apache.thrift.protocol.TMessageType.ONEWAY, 0));
         update_args args = new update_args();
         args.setWriter(writer);
         args.setCells(cells);
@@ -5611,6 +6541,736 @@
       }
     }
 
+    public void systemNamespace(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      systemNamespace_call method_call = new systemNamespace_call(resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class systemNamespace_call extends org.apache.thrift.async.TAsyncMethodCall {
+      public systemNamespace_call(org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("systemNamespace", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        systemNamespace_args args = new systemNamespace_args();
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public String getResult() throws org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_systemNamespace();
+      }
+    }
+
+    public void defaultNamespace(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      defaultNamespace_call method_call = new defaultNamespace_call(resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class defaultNamespace_call extends org.apache.thrift.async.TAsyncMethodCall {
+      public defaultNamespace_call(org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("defaultNamespace", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        defaultNamespace_args args = new defaultNamespace_args();
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public String getResult() throws org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_defaultNamespace();
+      }
+    }
+
+    public void listNamespaces(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      listNamespaces_call method_call = new listNamespaces_call(login, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class listNamespaces_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      public listNamespaces_call(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listNamespaces", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        listNamespaces_args args = new listNamespaces_args();
+        args.setLogin(login);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public List<String> getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_listNamespaces();
+      }
+    }
+
+    public void namespaceExists(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      namespaceExists_call method_call = new namespaceExists_call(login, namespaceName, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class namespaceExists_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      public namespaceExists_call(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("namespaceExists", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        namespaceExists_args args = new namespaceExists_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_namespaceExists();
+      }
+    }
+
+    public void createNamespace(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      createNamespace_call method_call = new createNamespace_call(login, namespaceName, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class createNamespace_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      public createNamespace_call(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createNamespace", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        createNamespace_args args = new createNamespace_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceExistsException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_createNamespace();
+      }
+    }
+
+    public void deleteNamespace(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      deleteNamespace_call method_call = new deleteNamespace_call(login, namespaceName, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class deleteNamespace_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      public deleteNamespace_call(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteNamespace", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        deleteNamespace_args args = new deleteNamespace_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceNotEmptyException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_deleteNamespace();
+      }
+    }
+
+    public void renameNamespace(ByteBuffer login, String oldNamespaceName, String newNamespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      renameNamespace_call method_call = new renameNamespace_call(login, oldNamespaceName, newNamespaceName, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class renameNamespace_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String oldNamespaceName;
+      private String newNamespaceName;
+      public renameNamespace_call(ByteBuffer login, String oldNamespaceName, String newNamespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.oldNamespaceName = oldNamespaceName;
+        this.newNamespaceName = newNamespaceName;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("renameNamespace", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        renameNamespace_args args = new renameNamespace_args();
+        args.setLogin(login);
+        args.setOldNamespaceName(oldNamespaceName);
+        args.setNewNamespaceName(newNamespaceName);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceExistsException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_renameNamespace();
+      }
+    }
+
+    public void setNamespaceProperty(ByteBuffer login, String namespaceName, String property, String value, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      setNamespaceProperty_call method_call = new setNamespaceProperty_call(login, namespaceName, property, value, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class setNamespaceProperty_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      private String property;
+      private String value;
+      public setNamespaceProperty_call(ByteBuffer login, String namespaceName, String property, String value, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+        this.property = property;
+        this.value = value;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("setNamespaceProperty", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        setNamespaceProperty_args args = new setNamespaceProperty_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.setProperty(property);
+        args.setValue(value);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_setNamespaceProperty();
+      }
+    }
+
+    public void removeNamespaceProperty(ByteBuffer login, String namespaceName, String property, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      removeNamespaceProperty_call method_call = new removeNamespaceProperty_call(login, namespaceName, property, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class removeNamespaceProperty_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      private String property;
+      public removeNamespaceProperty_call(ByteBuffer login, String namespaceName, String property, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+        this.property = property;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeNamespaceProperty", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        removeNamespaceProperty_args args = new removeNamespaceProperty_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.setProperty(property);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_removeNamespaceProperty();
+      }
+    }
+
+    public void getNamespaceProperties(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      getNamespaceProperties_call method_call = new getNamespaceProperties_call(login, namespaceName, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class getNamespaceProperties_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      public getNamespaceProperties_call(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getNamespaceProperties", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        getNamespaceProperties_args args = new getNamespaceProperties_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Map<String,String> getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_getNamespaceProperties();
+      }
+    }
+
+    public void namespaceIdMap(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      namespaceIdMap_call method_call = new namespaceIdMap_call(login, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class namespaceIdMap_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      public namespaceIdMap_call(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("namespaceIdMap", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        namespaceIdMap_args args = new namespaceIdMap_args();
+        args.setLogin(login);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Map<String,String> getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_namespaceIdMap();
+      }
+    }
+
+    public void attachNamespaceIterator(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      attachNamespaceIterator_call method_call = new attachNamespaceIterator_call(login, namespaceName, setting, scopes, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class attachNamespaceIterator_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      private IteratorSetting setting;
+      private Set<IteratorScope> scopes;
+      public attachNamespaceIterator_call(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+        this.setting = setting;
+        this.scopes = scopes;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("attachNamespaceIterator", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        attachNamespaceIterator_args args = new attachNamespaceIterator_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.setSetting(setting);
+        args.setScopes(scopes);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_attachNamespaceIterator();
+      }
+    }
+
+    public void removeNamespaceIterator(ByteBuffer login, String namespaceName, String name, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      removeNamespaceIterator_call method_call = new removeNamespaceIterator_call(login, namespaceName, name, scopes, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class removeNamespaceIterator_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      private String name;
+      private Set<IteratorScope> scopes;
+      public removeNamespaceIterator_call(ByteBuffer login, String namespaceName, String name, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+        this.name = name;
+        this.scopes = scopes;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeNamespaceIterator", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        removeNamespaceIterator_args args = new removeNamespaceIterator_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.setName(name);
+        args.setScopes(scopes);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_removeNamespaceIterator();
+      }
+    }
+
+    public void getNamespaceIteratorSetting(ByteBuffer login, String namespaceName, String name, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      getNamespaceIteratorSetting_call method_call = new getNamespaceIteratorSetting_call(login, namespaceName, name, scope, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class getNamespaceIteratorSetting_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      private String name;
+      private IteratorScope scope;
+      public getNamespaceIteratorSetting_call(ByteBuffer login, String namespaceName, String name, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+        this.name = name;
+        this.scope = scope;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getNamespaceIteratorSetting", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        getNamespaceIteratorSetting_args args = new getNamespaceIteratorSetting_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.setName(name);
+        args.setScope(scope);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public IteratorSetting getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_getNamespaceIteratorSetting();
+      }
+    }
+
+    public void listNamespaceIterators(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      listNamespaceIterators_call method_call = new listNamespaceIterators_call(login, namespaceName, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class listNamespaceIterators_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      public listNamespaceIterators_call(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listNamespaceIterators", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        listNamespaceIterators_args args = new listNamespaceIterators_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Map<String,Set<IteratorScope>> getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_listNamespaceIterators();
+      }
+    }
+
+    public void checkNamespaceIteratorConflicts(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      checkNamespaceIteratorConflicts_call method_call = new checkNamespaceIteratorConflicts_call(login, namespaceName, setting, scopes, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class checkNamespaceIteratorConflicts_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      private IteratorSetting setting;
+      private Set<IteratorScope> scopes;
+      public checkNamespaceIteratorConflicts_call(ByteBuffer login, String namespaceName, IteratorSetting setting, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+        this.setting = setting;
+        this.scopes = scopes;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("checkNamespaceIteratorConflicts", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        checkNamespaceIteratorConflicts_args args = new checkNamespaceIteratorConflicts_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.setSetting(setting);
+        args.setScopes(scopes);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_checkNamespaceIteratorConflicts();
+      }
+    }
+
+    public void addNamespaceConstraint(ByteBuffer login, String namespaceName, String constraintClassName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      addNamespaceConstraint_call method_call = new addNamespaceConstraint_call(login, namespaceName, constraintClassName, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class addNamespaceConstraint_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      private String constraintClassName;
+      public addNamespaceConstraint_call(ByteBuffer login, String namespaceName, String constraintClassName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+        this.constraintClassName = constraintClassName;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addNamespaceConstraint", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        addNamespaceConstraint_args args = new addNamespaceConstraint_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.setConstraintClassName(constraintClassName);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public int getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_addNamespaceConstraint();
+      }
+    }
+
+    public void removeNamespaceConstraint(ByteBuffer login, String namespaceName, int id, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      removeNamespaceConstraint_call method_call = new removeNamespaceConstraint_call(login, namespaceName, id, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class removeNamespaceConstraint_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      private int id;
+      public removeNamespaceConstraint_call(ByteBuffer login, String namespaceName, int id, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+        this.id = id;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeNamespaceConstraint", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        removeNamespaceConstraint_args args = new removeNamespaceConstraint_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.setId(id);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        (new Client(prot)).recv_removeNamespaceConstraint();
+      }
+    }
+
+    public void listNamespaceConstraints(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      listNamespaceConstraints_call method_call = new listNamespaceConstraints_call(login, namespaceName, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class listNamespaceConstraints_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      public listNamespaceConstraints_call(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("listNamespaceConstraints", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        listNamespaceConstraints_args args = new listNamespaceConstraints_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Map<String,Integer> getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_listNamespaceConstraints();
+      }
+    }
+
+    public void testNamespaceClassLoad(ByteBuffer login, String namespaceName, String className, String asTypeName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      testNamespaceClassLoad_call method_call = new testNamespaceClassLoad_call(login, namespaceName, className, asTypeName, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class testNamespaceClassLoad_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer login;
+      private String namespaceName;
+      private String className;
+      private String asTypeName;
+      public testNamespaceClassLoad_call(ByteBuffer login, String namespaceName, String className, String asTypeName, org.apache.thrift.async.AsyncMethodCallback resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.login = login;
+        this.namespaceName = namespaceName;
+        this.className = className;
+        this.asTypeName = asTypeName;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("testNamespaceClassLoad", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        testNamespaceClassLoad_args args = new testNamespaceClassLoad_args();
+        args.setLogin(login);
+        args.setNamespaceName(namespaceName);
+        args.setClassName(className);
+        args.setAsTypeName(asTypeName);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public boolean getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_testNamespaceClassLoad();
+      }
+    }
+
   }
 
   public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
@@ -5684,6 +7344,9 @@
       processMap.put("listLocalUsers", new listLocalUsers());
       processMap.put("revokeSystemPermission", new revokeSystemPermission());
       processMap.put("revokeTablePermission", new revokeTablePermission());
+      processMap.put("grantNamespacePermission", new grantNamespacePermission());
+      processMap.put("hasNamespacePermission", new hasNamespacePermission());
+      processMap.put("revokeNamespacePermission", new revokeNamespacePermission());
       processMap.put("createBatchScanner", new createBatchScanner());
       processMap.put("createScanner", new createScanner());
       processMap.put("hasNext", new hasNext());
@@ -5701,6 +7364,26 @@
       processMap.put("closeConditionalWriter", new closeConditionalWriter());
       processMap.put("getRowRange", new getRowRange());
       processMap.put("getFollowing", new getFollowing());
+      processMap.put("systemNamespace", new systemNamespace());
+      processMap.put("defaultNamespace", new defaultNamespace());
+      processMap.put("listNamespaces", new listNamespaces());
+      processMap.put("namespaceExists", new namespaceExists());
+      processMap.put("createNamespace", new createNamespace());
+      processMap.put("deleteNamespace", new deleteNamespace());
+      processMap.put("renameNamespace", new renameNamespace());
+      processMap.put("setNamespaceProperty", new setNamespaceProperty());
+      processMap.put("removeNamespaceProperty", new removeNamespaceProperty());
+      processMap.put("getNamespaceProperties", new getNamespaceProperties());
+      processMap.put("namespaceIdMap", new namespaceIdMap());
+      processMap.put("attachNamespaceIterator", new attachNamespaceIterator());
+      processMap.put("removeNamespaceIterator", new removeNamespaceIterator());
+      processMap.put("getNamespaceIteratorSetting", new getNamespaceIteratorSetting());
+      processMap.put("listNamespaceIterators", new listNamespaceIterators());
+      processMap.put("checkNamespaceIteratorConflicts", new checkNamespaceIteratorConflicts());
+      processMap.put("addNamespaceConstraint", new addNamespaceConstraint());
+      processMap.put("removeNamespaceConstraint", new removeNamespaceConstraint());
+      processMap.put("listNamespaceConstraints", new listNamespaceConstraints());
+      processMap.put("testNamespaceClassLoad", new testNamespaceClassLoad());
       return processMap;
     }
 
@@ -7321,6 +9004,85 @@
       }
     }
 
+    public static class grantNamespacePermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, grantNamespacePermission_args> {
+      public grantNamespacePermission() {
+        super("grantNamespacePermission");
+      }
+
+      public grantNamespacePermission_args getEmptyArgsInstance() {
+        return new grantNamespacePermission_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public grantNamespacePermission_result getResult(I iface, grantNamespacePermission_args args) throws org.apache.thrift.TException {
+        grantNamespacePermission_result result = new grantNamespacePermission_result();
+        try {
+          iface.grantNamespacePermission(args.login, args.user, args.namespaceName, args.perm);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        }
+        return result;
+      }
+    }
+
+    public static class hasNamespacePermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, hasNamespacePermission_args> {
+      public hasNamespacePermission() {
+        super("hasNamespacePermission");
+      }
+
+      public hasNamespacePermission_args getEmptyArgsInstance() {
+        return new hasNamespacePermission_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public hasNamespacePermission_result getResult(I iface, hasNamespacePermission_args args) throws org.apache.thrift.TException {
+        hasNamespacePermission_result result = new hasNamespacePermission_result();
+        try {
+          result.success = iface.hasNamespacePermission(args.login, args.user, args.namespaceName, args.perm);
+          result.setSuccessIsSet(true);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        }
+        return result;
+      }
+    }
+
+    public static class revokeNamespacePermission<I extends Iface> extends org.apache.thrift.ProcessFunction<I, revokeNamespacePermission_args> {
+      public revokeNamespacePermission() {
+        super("revokeNamespacePermission");
+      }
+
+      public revokeNamespacePermission_args getEmptyArgsInstance() {
+        return new revokeNamespacePermission_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public revokeNamespacePermission_result getResult(I iface, revokeNamespacePermission_args args) throws org.apache.thrift.TException {
+        revokeNamespacePermission_result result = new revokeNamespacePermission_result();
+        try {
+          iface.revokeNamespacePermission(args.login, args.user, args.namespaceName, args.perm);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        }
+        return result;
+      }
+    }
+
     public static class createBatchScanner<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createBatchScanner_args> {
       public createBatchScanner() {
         super("createBatchScanner");
@@ -7755,6 +9517,551 @@
       }
     }
 
+    public static class systemNamespace<I extends Iface> extends org.apache.thrift.ProcessFunction<I, systemNamespace_args> {
+      public systemNamespace() {
+        super("systemNamespace");
+      }
+
+      public systemNamespace_args getEmptyArgsInstance() {
+        return new systemNamespace_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public systemNamespace_result getResult(I iface, systemNamespace_args args) throws org.apache.thrift.TException {
+        systemNamespace_result result = new systemNamespace_result();
+        result.success = iface.systemNamespace();
+        return result;
+      }
+    }
+
+    public static class defaultNamespace<I extends Iface> extends org.apache.thrift.ProcessFunction<I, defaultNamespace_args> {
+      public defaultNamespace() {
+        super("defaultNamespace");
+      }
+
+      public defaultNamespace_args getEmptyArgsInstance() {
+        return new defaultNamespace_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public defaultNamespace_result getResult(I iface, defaultNamespace_args args) throws org.apache.thrift.TException {
+        defaultNamespace_result result = new defaultNamespace_result();
+        result.success = iface.defaultNamespace();
+        return result;
+      }
+    }
+
+    public static class listNamespaces<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listNamespaces_args> {
+      public listNamespaces() {
+        super("listNamespaces");
+      }
+
+      public listNamespaces_args getEmptyArgsInstance() {
+        return new listNamespaces_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public listNamespaces_result getResult(I iface, listNamespaces_args args) throws org.apache.thrift.TException {
+        listNamespaces_result result = new listNamespaces_result();
+        try {
+          result.success = iface.listNamespaces(args.login);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        }
+        return result;
+      }
+    }
+
+    public static class namespaceExists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, namespaceExists_args> {
+      public namespaceExists() {
+        super("namespaceExists");
+      }
+
+      public namespaceExists_args getEmptyArgsInstance() {
+        return new namespaceExists_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public namespaceExists_result getResult(I iface, namespaceExists_args args) throws org.apache.thrift.TException {
+        namespaceExists_result result = new namespaceExists_result();
+        try {
+          result.success = iface.namespaceExists(args.login, args.namespaceName);
+          result.setSuccessIsSet(true);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        }
+        return result;
+      }
+    }
+
+    public static class createNamespace<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createNamespace_args> {
+      public createNamespace() {
+        super("createNamespace");
+      }
+
+      public createNamespace_args getEmptyArgsInstance() {
+        return new createNamespace_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public createNamespace_result getResult(I iface, createNamespace_args args) throws org.apache.thrift.TException {
+        createNamespace_result result = new createNamespace_result();
+        try {
+          iface.createNamespace(args.login, args.namespaceName);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceExistsException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class deleteNamespace<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteNamespace_args> {
+      public deleteNamespace() {
+        super("deleteNamespace");
+      }
+
+      public deleteNamespace_args getEmptyArgsInstance() {
+        return new deleteNamespace_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public deleteNamespace_result getResult(I iface, deleteNamespace_args args) throws org.apache.thrift.TException {
+        deleteNamespace_result result = new deleteNamespace_result();
+        try {
+          iface.deleteNamespace(args.login, args.namespaceName);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        } catch (NamespaceNotEmptyException ouch4) {
+          result.ouch4 = ouch4;
+        }
+        return result;
+      }
+    }
+
+    public static class renameNamespace<I extends Iface> extends org.apache.thrift.ProcessFunction<I, renameNamespace_args> {
+      public renameNamespace() {
+        super("renameNamespace");
+      }
+
+      public renameNamespace_args getEmptyArgsInstance() {
+        return new renameNamespace_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public renameNamespace_result getResult(I iface, renameNamespace_args args) throws org.apache.thrift.TException {
+        renameNamespace_result result = new renameNamespace_result();
+        try {
+          iface.renameNamespace(args.login, args.oldNamespaceName, args.newNamespaceName);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        } catch (NamespaceExistsException ouch4) {
+          result.ouch4 = ouch4;
+        }
+        return result;
+      }
+    }
+
+    public static class setNamespaceProperty<I extends Iface> extends org.apache.thrift.ProcessFunction<I, setNamespaceProperty_args> {
+      public setNamespaceProperty() {
+        super("setNamespaceProperty");
+      }
+
+      public setNamespaceProperty_args getEmptyArgsInstance() {
+        return new setNamespaceProperty_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public setNamespaceProperty_result getResult(I iface, setNamespaceProperty_args args) throws org.apache.thrift.TException {
+        setNamespaceProperty_result result = new setNamespaceProperty_result();
+        try {
+          iface.setNamespaceProperty(args.login, args.namespaceName, args.property, args.value);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class removeNamespaceProperty<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeNamespaceProperty_args> {
+      public removeNamespaceProperty() {
+        super("removeNamespaceProperty");
+      }
+
+      public removeNamespaceProperty_args getEmptyArgsInstance() {
+        return new removeNamespaceProperty_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public removeNamespaceProperty_result getResult(I iface, removeNamespaceProperty_args args) throws org.apache.thrift.TException {
+        removeNamespaceProperty_result result = new removeNamespaceProperty_result();
+        try {
+          iface.removeNamespaceProperty(args.login, args.namespaceName, args.property);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class getNamespaceProperties<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getNamespaceProperties_args> {
+      public getNamespaceProperties() {
+        super("getNamespaceProperties");
+      }
+
+      public getNamespaceProperties_args getEmptyArgsInstance() {
+        return new getNamespaceProperties_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public getNamespaceProperties_result getResult(I iface, getNamespaceProperties_args args) throws org.apache.thrift.TException {
+        getNamespaceProperties_result result = new getNamespaceProperties_result();
+        try {
+          result.success = iface.getNamespaceProperties(args.login, args.namespaceName);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class namespaceIdMap<I extends Iface> extends org.apache.thrift.ProcessFunction<I, namespaceIdMap_args> {
+      public namespaceIdMap() {
+        super("namespaceIdMap");
+      }
+
+      public namespaceIdMap_args getEmptyArgsInstance() {
+        return new namespaceIdMap_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public namespaceIdMap_result getResult(I iface, namespaceIdMap_args args) throws org.apache.thrift.TException {
+        namespaceIdMap_result result = new namespaceIdMap_result();
+        try {
+          result.success = iface.namespaceIdMap(args.login);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        }
+        return result;
+      }
+    }
+
+    public static class attachNamespaceIterator<I extends Iface> extends org.apache.thrift.ProcessFunction<I, attachNamespaceIterator_args> {
+      public attachNamespaceIterator() {
+        super("attachNamespaceIterator");
+      }
+
+      public attachNamespaceIterator_args getEmptyArgsInstance() {
+        return new attachNamespaceIterator_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public attachNamespaceIterator_result getResult(I iface, attachNamespaceIterator_args args) throws org.apache.thrift.TException {
+        attachNamespaceIterator_result result = new attachNamespaceIterator_result();
+        try {
+          iface.attachNamespaceIterator(args.login, args.namespaceName, args.setting, args.scopes);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class removeNamespaceIterator<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeNamespaceIterator_args> {
+      public removeNamespaceIterator() {
+        super("removeNamespaceIterator");
+      }
+
+      public removeNamespaceIterator_args getEmptyArgsInstance() {
+        return new removeNamespaceIterator_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public removeNamespaceIterator_result getResult(I iface, removeNamespaceIterator_args args) throws org.apache.thrift.TException {
+        removeNamespaceIterator_result result = new removeNamespaceIterator_result();
+        try {
+          iface.removeNamespaceIterator(args.login, args.namespaceName, args.name, args.scopes);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class getNamespaceIteratorSetting<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getNamespaceIteratorSetting_args> {
+      public getNamespaceIteratorSetting() {
+        super("getNamespaceIteratorSetting");
+      }
+
+      public getNamespaceIteratorSetting_args getEmptyArgsInstance() {
+        return new getNamespaceIteratorSetting_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public getNamespaceIteratorSetting_result getResult(I iface, getNamespaceIteratorSetting_args args) throws org.apache.thrift.TException {
+        getNamespaceIteratorSetting_result result = new getNamespaceIteratorSetting_result();
+        try {
+          result.success = iface.getNamespaceIteratorSetting(args.login, args.namespaceName, args.name, args.scope);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class listNamespaceIterators<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listNamespaceIterators_args> {
+      public listNamespaceIterators() {
+        super("listNamespaceIterators");
+      }
+
+      public listNamespaceIterators_args getEmptyArgsInstance() {
+        return new listNamespaceIterators_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public listNamespaceIterators_result getResult(I iface, listNamespaceIterators_args args) throws org.apache.thrift.TException {
+        listNamespaceIterators_result result = new listNamespaceIterators_result();
+        try {
+          result.success = iface.listNamespaceIterators(args.login, args.namespaceName);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class checkNamespaceIteratorConflicts<I extends Iface> extends org.apache.thrift.ProcessFunction<I, checkNamespaceIteratorConflicts_args> {
+      public checkNamespaceIteratorConflicts() {
+        super("checkNamespaceIteratorConflicts");
+      }
+
+      public checkNamespaceIteratorConflicts_args getEmptyArgsInstance() {
+        return new checkNamespaceIteratorConflicts_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public checkNamespaceIteratorConflicts_result getResult(I iface, checkNamespaceIteratorConflicts_args args) throws org.apache.thrift.TException {
+        checkNamespaceIteratorConflicts_result result = new checkNamespaceIteratorConflicts_result();
+        try {
+          iface.checkNamespaceIteratorConflicts(args.login, args.namespaceName, args.setting, args.scopes);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class addNamespaceConstraint<I extends Iface> extends org.apache.thrift.ProcessFunction<I, addNamespaceConstraint_args> {
+      public addNamespaceConstraint() {
+        super("addNamespaceConstraint");
+      }
+
+      public addNamespaceConstraint_args getEmptyArgsInstance() {
+        return new addNamespaceConstraint_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public addNamespaceConstraint_result getResult(I iface, addNamespaceConstraint_args args) throws org.apache.thrift.TException {
+        addNamespaceConstraint_result result = new addNamespaceConstraint_result();
+        try {
+          result.success = iface.addNamespaceConstraint(args.login, args.namespaceName, args.constraintClassName);
+          result.setSuccessIsSet(true);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class removeNamespaceConstraint<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeNamespaceConstraint_args> {
+      public removeNamespaceConstraint() {
+        super("removeNamespaceConstraint");
+      }
+
+      public removeNamespaceConstraint_args getEmptyArgsInstance() {
+        return new removeNamespaceConstraint_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public removeNamespaceConstraint_result getResult(I iface, removeNamespaceConstraint_args args) throws org.apache.thrift.TException {
+        removeNamespaceConstraint_result result = new removeNamespaceConstraint_result();
+        try {
+          iface.removeNamespaceConstraint(args.login, args.namespaceName, args.id);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class listNamespaceConstraints<I extends Iface> extends org.apache.thrift.ProcessFunction<I, listNamespaceConstraints_args> {
+      public listNamespaceConstraints() {
+        super("listNamespaceConstraints");
+      }
+
+      public listNamespaceConstraints_args getEmptyArgsInstance() {
+        return new listNamespaceConstraints_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public listNamespaceConstraints_result getResult(I iface, listNamespaceConstraints_args args) throws org.apache.thrift.TException {
+        listNamespaceConstraints_result result = new listNamespaceConstraints_result();
+        try {
+          result.success = iface.listNamespaceConstraints(args.login, args.namespaceName);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
+    public static class testNamespaceClassLoad<I extends Iface> extends org.apache.thrift.ProcessFunction<I, testNamespaceClassLoad_args> {
+      public testNamespaceClassLoad() {
+        super("testNamespaceClassLoad");
+      }
+
+      public testNamespaceClassLoad_args getEmptyArgsInstance() {
+        return new testNamespaceClassLoad_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public testNamespaceClassLoad_result getResult(I iface, testNamespaceClassLoad_args args) throws org.apache.thrift.TException {
+        testNamespaceClassLoad_result result = new testNamespaceClassLoad_result();
+        try {
+          result.success = iface.testNamespaceClassLoad(args.login, args.namespaceName, args.className, args.asTypeName);
+          result.setSuccessIsSet(true);
+        } catch (AccumuloException ouch1) {
+          result.ouch1 = ouch1;
+        } catch (AccumuloSecurityException ouch2) {
+          result.ouch2 = ouch2;
+        } catch (NamespaceNotFoundException ouch3) {
+          result.ouch3 = ouch3;
+        }
+        return result;
+      }
+    }
+
   }
 
   public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> {
@@ -7828,6 +10135,9 @@
       processMap.put("listLocalUsers", new listLocalUsers());
       processMap.put("revokeSystemPermission", new revokeSystemPermission());
       processMap.put("revokeTablePermission", new revokeTablePermission());
+      processMap.put("grantNamespacePermission", new grantNamespacePermission());
+      processMap.put("hasNamespacePermission", new hasNamespacePermission());
+      processMap.put("revokeNamespacePermission", new revokeNamespacePermission());
       processMap.put("createBatchScanner", new createBatchScanner());
       processMap.put("createScanner", new createScanner());
       processMap.put("hasNext", new hasNext());
@@ -7845,6 +10155,26 @@
       processMap.put("closeConditionalWriter", new closeConditionalWriter());
       processMap.put("getRowRange", new getRowRange());
       processMap.put("getFollowing", new getFollowing());
+      processMap.put("systemNamespace", new systemNamespace());
+      processMap.put("defaultNamespace", new defaultNamespace());
+      processMap.put("listNamespaces", new listNamespaces());
+      processMap.put("namespaceExists", new namespaceExists());
+      processMap.put("createNamespace", new createNamespace());
+      processMap.put("deleteNamespace", new deleteNamespace());
+      processMap.put("renameNamespace", new renameNamespace());
+      processMap.put("setNamespaceProperty", new setNamespaceProperty());
+      processMap.put("removeNamespaceProperty", new removeNamespaceProperty());
+      processMap.put("getNamespaceProperties", new getNamespaceProperties());
+      processMap.put("namespaceIdMap", new namespaceIdMap());
+      processMap.put("attachNamespaceIterator", new attachNamespaceIterator());
+      processMap.put("removeNamespaceIterator", new removeNamespaceIterator());
+      processMap.put("getNamespaceIteratorSetting", new getNamespaceIteratorSetting());
+      processMap.put("listNamespaceIterators", new listNamespaceIterators());
+      processMap.put("checkNamespaceIteratorConflicts", new checkNamespaceIteratorConflicts());
+      processMap.put("addNamespaceConstraint", new addNamespaceConstraint());
+      processMap.put("removeNamespaceConstraint", new removeNamespaceConstraint());
+      processMap.put("listNamespaceConstraints", new listNamespaceConstraints());
+      processMap.put("testNamespaceClassLoad", new testNamespaceClassLoad());
       return processMap;
     }
 
@@ -11682,6 +14012,191 @@
       }
     }
 
+    public static class grantNamespacePermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, grantNamespacePermission_args, Void> {
+      public grantNamespacePermission() {
+        super("grantNamespacePermission");
+      }
+
+      public grantNamespacePermission_args getEmptyArgsInstance() {
+        return new grantNamespacePermission_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            grantNamespacePermission_result result = new grantNamespacePermission_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            grantNamespacePermission_result result = new grantNamespacePermission_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, grantNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.grantNamespacePermission(args.login, args.user, args.namespaceName, args.perm,resultHandler);
+      }
+    }
+
+    public static class hasNamespacePermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, hasNamespacePermission_args, Boolean> {
+      public hasNamespacePermission() {
+        super("hasNamespacePermission");
+      }
+
+      public hasNamespacePermission_args getEmptyArgsInstance() {
+        return new hasNamespacePermission_args();
+      }
+
+      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Boolean>() { 
+          public void onComplete(Boolean o) {
+            hasNamespacePermission_result result = new hasNamespacePermission_result();
+            result.success = o;
+            result.setSuccessIsSet(true);
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            hasNamespacePermission_result result = new hasNamespacePermission_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, hasNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+        iface.hasNamespacePermission(args.login, args.user, args.namespaceName, args.perm,resultHandler);
+      }
+    }
+
+    public static class revokeNamespacePermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, revokeNamespacePermission_args, Void> {
+      public revokeNamespacePermission() {
+        super("revokeNamespacePermission");
+      }
+
+      public revokeNamespacePermission_args getEmptyArgsInstance() {
+        return new revokeNamespacePermission_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            revokeNamespacePermission_result result = new revokeNamespacePermission_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            revokeNamespacePermission_result result = new revokeNamespacePermission_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, revokeNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.revokeNamespacePermission(args.login, args.user, args.namespaceName, args.perm,resultHandler);
+      }
+    }
+
     public static class createBatchScanner<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createBatchScanner_args, String> {
       public createBatchScanner() {
         super("createBatchScanner");
@@ -12705,6 +15220,1303 @@
       }
     }
 
+    public static class systemNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, systemNamespace_args, String> {
+      public systemNamespace() {
+        super("systemNamespace");
+      }
+
+      public systemNamespace_args getEmptyArgsInstance() {
+        return new systemNamespace_args();
+      }
+
+      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<String>() { 
+          public void onComplete(String o) {
+            systemNamespace_result result = new systemNamespace_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            systemNamespace_result result = new systemNamespace_result();
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, systemNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
+        iface.systemNamespace(resultHandler);
+      }
+    }
+
+    public static class defaultNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, defaultNamespace_args, String> {
+      public defaultNamespace() {
+        super("defaultNamespace");
+      }
+
+      public defaultNamespace_args getEmptyArgsInstance() {
+        return new defaultNamespace_args();
+      }
+
+      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<String>() { 
+          public void onComplete(String o) {
+            defaultNamespace_result result = new defaultNamespace_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            defaultNamespace_result result = new defaultNamespace_result();
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, defaultNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
+        iface.defaultNamespace(resultHandler);
+      }
+    }
+
+    public static class listNamespaces<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listNamespaces_args, List<String>> {
+      public listNamespaces() {
+        super("listNamespaces");
+      }
+
+      public listNamespaces_args getEmptyArgsInstance() {
+        return new listNamespaces_args();
+      }
+
+      public AsyncMethodCallback<List<String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<List<String>>() { 
+          public void onComplete(List<String> o) {
+            listNamespaces_result result = new listNamespaces_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            listNamespaces_result result = new listNamespaces_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, listNamespaces_args args, org.apache.thrift.async.AsyncMethodCallback<List<String>> resultHandler) throws TException {
+        iface.listNamespaces(args.login,resultHandler);
+      }
+    }
+
+    public static class namespaceExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, namespaceExists_args, Boolean> {
+      public namespaceExists() {
+        super("namespaceExists");
+      }
+
+      public namespaceExists_args getEmptyArgsInstance() {
+        return new namespaceExists_args();
+      }
+
+      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Boolean>() { 
+          public void onComplete(Boolean o) {
+            namespaceExists_result result = new namespaceExists_result();
+            result.success = o;
+            result.setSuccessIsSet(true);
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            namespaceExists_result result = new namespaceExists_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, namespaceExists_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+        iface.namespaceExists(args.login, args.namespaceName,resultHandler);
+      }
+    }
+
+    public static class createNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createNamespace_args, Void> {
+      public createNamespace() {
+        super("createNamespace");
+      }
+
+      public createNamespace_args getEmptyArgsInstance() {
+        return new createNamespace_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            createNamespace_result result = new createNamespace_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            createNamespace_result result = new createNamespace_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceExistsException) {
+                        result.ouch3 = (NamespaceExistsException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, createNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.createNamespace(args.login, args.namespaceName,resultHandler);
+      }
+    }
+
+    public static class deleteNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteNamespace_args, Void> {
+      public deleteNamespace() {
+        super("deleteNamespace");
+      }
+
+      public deleteNamespace_args getEmptyArgsInstance() {
+        return new deleteNamespace_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            deleteNamespace_result result = new deleteNamespace_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            deleteNamespace_result result = new deleteNamespace_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotEmptyException) {
+                        result.ouch4 = (NamespaceNotEmptyException) e;
+                        result.setOuch4IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, deleteNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.deleteNamespace(args.login, args.namespaceName,resultHandler);
+      }
+    }
+
+    public static class renameNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, renameNamespace_args, Void> {
+      public renameNamespace() {
+        super("renameNamespace");
+      }
+
+      public renameNamespace_args getEmptyArgsInstance() {
+        return new renameNamespace_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            renameNamespace_result result = new renameNamespace_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            renameNamespace_result result = new renameNamespace_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceExistsException) {
+                        result.ouch4 = (NamespaceExistsException) e;
+                        result.setOuch4IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, renameNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.renameNamespace(args.login, args.oldNamespaceName, args.newNamespaceName,resultHandler);
+      }
+    }
+
+    public static class setNamespaceProperty<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, setNamespaceProperty_args, Void> {
+      public setNamespaceProperty() {
+        super("setNamespaceProperty");
+      }
+
+      public setNamespaceProperty_args getEmptyArgsInstance() {
+        return new setNamespaceProperty_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            setNamespaceProperty_result result = new setNamespaceProperty_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            setNamespaceProperty_result result = new setNamespaceProperty_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, setNamespaceProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.setNamespaceProperty(args.login, args.namespaceName, args.property, args.value,resultHandler);
+      }
+    }
+
+    public static class removeNamespaceProperty<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeNamespaceProperty_args, Void> {
+      public removeNamespaceProperty() {
+        super("removeNamespaceProperty");
+      }
+
+      public removeNamespaceProperty_args getEmptyArgsInstance() {
+        return new removeNamespaceProperty_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            removeNamespaceProperty_result result = new removeNamespaceProperty_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            removeNamespaceProperty_result result = new removeNamespaceProperty_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, removeNamespaceProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.removeNamespaceProperty(args.login, args.namespaceName, args.property,resultHandler);
+      }
+    }
+
+    public static class getNamespaceProperties<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getNamespaceProperties_args, Map<String,String>> {
+      public getNamespaceProperties() {
+        super("getNamespaceProperties");
+      }
+
+      public getNamespaceProperties_args getEmptyArgsInstance() {
+        return new getNamespaceProperties_args();
+      }
+
+      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Map<String,String>>() { 
+          public void onComplete(Map<String,String> o) {
+            getNamespaceProperties_result result = new getNamespaceProperties_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            getNamespaceProperties_result result = new getNamespaceProperties_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, getNamespaceProperties_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
+        iface.getNamespaceProperties(args.login, args.namespaceName,resultHandler);
+      }
+    }
+
+    public static class namespaceIdMap<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, namespaceIdMap_args, Map<String,String>> {
+      public namespaceIdMap() {
+        super("namespaceIdMap");
+      }
+
+      public namespaceIdMap_args getEmptyArgsInstance() {
+        return new namespaceIdMap_args();
+      }
+
+      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Map<String,String>>() { 
+          public void onComplete(Map<String,String> o) {
+            namespaceIdMap_result result = new namespaceIdMap_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            namespaceIdMap_result result = new namespaceIdMap_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, namespaceIdMap_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
+        iface.namespaceIdMap(args.login,resultHandler);
+      }
+    }
+
+    public static class attachNamespaceIterator<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, attachNamespaceIterator_args, Void> {
+      public attachNamespaceIterator() {
+        super("attachNamespaceIterator");
+      }
+
+      public attachNamespaceIterator_args getEmptyArgsInstance() {
+        return new attachNamespaceIterator_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            attachNamespaceIterator_result result = new attachNamespaceIterator_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            attachNamespaceIterator_result result = new attachNamespaceIterator_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, attachNamespaceIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.attachNamespaceIterator(args.login, args.namespaceName, args.setting, args.scopes,resultHandler);
+      }
+    }
+
+    public static class removeNamespaceIterator<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeNamespaceIterator_args, Void> {
+      public removeNamespaceIterator() {
+        super("removeNamespaceIterator");
+      }
+
+      public removeNamespaceIterator_args getEmptyArgsInstance() {
+        return new removeNamespaceIterator_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            removeNamespaceIterator_result result = new removeNamespaceIterator_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            removeNamespaceIterator_result result = new removeNamespaceIterator_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, removeNamespaceIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.removeNamespaceIterator(args.login, args.namespaceName, args.name, args.scopes,resultHandler);
+      }
+    }
+
+    public static class getNamespaceIteratorSetting<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getNamespaceIteratorSetting_args, IteratorSetting> {
+      public getNamespaceIteratorSetting() {
+        super("getNamespaceIteratorSetting");
+      }
+
+      public getNamespaceIteratorSetting_args getEmptyArgsInstance() {
+        return new getNamespaceIteratorSetting_args();
+      }
+
+      public AsyncMethodCallback<IteratorSetting> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<IteratorSetting>() { 
+          public void onComplete(IteratorSetting o) {
+            getNamespaceIteratorSetting_result result = new getNamespaceIteratorSetting_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            getNamespaceIteratorSetting_result result = new getNamespaceIteratorSetting_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, getNamespaceIteratorSetting_args args, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> resultHandler) throws TException {
+        iface.getNamespaceIteratorSetting(args.login, args.namespaceName, args.name, args.scope,resultHandler);
+      }
+    }
+
+    public static class listNamespaceIterators<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listNamespaceIterators_args, Map<String,Set<IteratorScope>>> {
+      public listNamespaceIterators() {
+        super("listNamespaceIterators");
+      }
+
+      public listNamespaceIterators_args getEmptyArgsInstance() {
+        return new listNamespaceIterators_args();
+      }
+
+      public AsyncMethodCallback<Map<String,Set<IteratorScope>>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Map<String,Set<IteratorScope>>>() { 
+          public void onComplete(Map<String,Set<IteratorScope>> o) {
+            listNamespaceIterators_result result = new listNamespaceIterators_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            listNamespaceIterators_result result = new listNamespaceIterators_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, listNamespaceIterators_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,Set<IteratorScope>>> resultHandler) throws TException {
+        iface.listNamespaceIterators(args.login, args.namespaceName,resultHandler);
+      }
+    }
+
+    public static class checkNamespaceIteratorConflicts<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, checkNamespaceIteratorConflicts_args, Void> {
+      public checkNamespaceIteratorConflicts() {
+        super("checkNamespaceIteratorConflicts");
+      }
+
+      public checkNamespaceIteratorConflicts_args getEmptyArgsInstance() {
+        return new checkNamespaceIteratorConflicts_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            checkNamespaceIteratorConflicts_result result = new checkNamespaceIteratorConflicts_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            checkNamespaceIteratorConflicts_result result = new checkNamespaceIteratorConflicts_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, checkNamespaceIteratorConflicts_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.checkNamespaceIteratorConflicts(args.login, args.namespaceName, args.setting, args.scopes,resultHandler);
+      }
+    }
+
+    public static class addNamespaceConstraint<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addNamespaceConstraint_args, Integer> {
+      public addNamespaceConstraint() {
+        super("addNamespaceConstraint");
+      }
+
+      public addNamespaceConstraint_args getEmptyArgsInstance() {
+        return new addNamespaceConstraint_args();
+      }
+
+      public AsyncMethodCallback<Integer> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Integer>() { 
+          public void onComplete(Integer o) {
+            addNamespaceConstraint_result result = new addNamespaceConstraint_result();
+            result.success = o;
+            result.setSuccessIsSet(true);
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            addNamespaceConstraint_result result = new addNamespaceConstraint_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, addNamespaceConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws TException {
+        iface.addNamespaceConstraint(args.login, args.namespaceName, args.constraintClassName,resultHandler);
+      }
+    }
+
+    public static class removeNamespaceConstraint<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeNamespaceConstraint_args, Void> {
+      public removeNamespaceConstraint() {
+        super("removeNamespaceConstraint");
+      }
+
+      public removeNamespaceConstraint_args getEmptyArgsInstance() {
+        return new removeNamespaceConstraint_args();
+      }
+
+      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            removeNamespaceConstraint_result result = new removeNamespaceConstraint_result();
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            removeNamespaceConstraint_result result = new removeNamespaceConstraint_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, removeNamespaceConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+        iface.removeNamespaceConstraint(args.login, args.namespaceName, args.id,resultHandler);
+      }
+    }
+
+    public static class listNamespaceConstraints<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listNamespaceConstraints_args, Map<String,Integer>> {
+      public listNamespaceConstraints() {
+        super("listNamespaceConstraints");
+      }
+
+      public listNamespaceConstraints_args getEmptyArgsInstance() {
+        return new listNamespaceConstraints_args();
+      }
+
+      public AsyncMethodCallback<Map<String,Integer>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Map<String,Integer>>() { 
+          public void onComplete(Map<String,Integer> o) {
+            listNamespaceConstraints_result result = new listNamespaceConstraints_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            listNamespaceConstraints_result result = new listNamespaceConstraints_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, listNamespaceConstraints_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,Integer>> resultHandler) throws TException {
+        iface.listNamespaceConstraints(args.login, args.namespaceName,resultHandler);
+      }
+    }
+
+    public static class testNamespaceClassLoad<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, testNamespaceClassLoad_args, Boolean> {
+      public testNamespaceClassLoad() {
+        super("testNamespaceClassLoad");
+      }
+
+      public testNamespaceClassLoad_args getEmptyArgsInstance() {
+        return new testNamespaceClassLoad_args();
+      }
+
+      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new AsyncMethodCallback<Boolean>() { 
+          public void onComplete(Boolean o) {
+            testNamespaceClassLoad_result result = new testNamespaceClassLoad_result();
+            result.success = o;
+            result.setSuccessIsSet(true);
+            try {
+              fcall.sendResponse(fb,result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+              return;
+            } catch (Exception e) {
+              LOGGER.error("Exception writing to internal frame buffer", e);
+            }
+            fb.close();
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TBase msg;
+            testNamespaceClassLoad_result result = new testNamespaceClassLoad_result();
+            if (e instanceof AccumuloException) {
+                        result.ouch1 = (AccumuloException) e;
+                        result.setOuch1IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof AccumuloSecurityException) {
+                        result.ouch2 = (AccumuloSecurityException) e;
+                        result.setOuch2IsSet(true);
+                        msg = result;
+            }
+            else             if (e instanceof NamespaceNotFoundException) {
+                        result.ouch3 = (NamespaceNotFoundException) e;
+                        result.setOuch3IsSet(true);
+                        msg = result;
+            }
+             else 
+            {
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TBase)new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+              return;
+            } catch (Exception ex) {
+              LOGGER.error("Exception writing to internal frame buffer", ex);
+            }
+            fb.close();
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, testNamespaceClassLoad_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+        iface.testNamespaceClassLoad(args.login, args.namespaceName, args.className, args.asTypeName,resultHandler);
+      }
+    }
+
   }
 
   public static class login_args implements org.apache.thrift.TBase<login_args, login_args._Fields>, java.io.Serializable, Cloneable, Comparable<login_args>   {
@@ -12975,7 +16787,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_principal = true && (isSetPrincipal());
+      list.add(present_principal);
+      if (present_principal)
+        list.add(principal);
+
+      boolean present_loginProperties = true && (isSetLoginProperties());
+      list.add(present_loginProperties);
+      if (present_loginProperties)
+        list.add(loginProperties);
+
+      return list.hashCode();
     }
 
     @Override
@@ -13097,13 +16921,13 @@
                 {
                   org.apache.thrift.protocol.TMap _map164 = iprot.readMapBegin();
                   struct.loginProperties = new HashMap<String,String>(2*_map164.size);
-                  for (int _i165 = 0; _i165 < _map164.size; ++_i165)
+                  String _key165;
+                  String _val166;
+                  for (int _i167 = 0; _i167 < _map164.size; ++_i167)
                   {
-                    String _key166;
-                    String _val167;
-                    _key166 = iprot.readString();
-                    _val167 = iprot.readString();
-                    struct.loginProperties.put(_key166, _val167);
+                    _key165 = iprot.readString();
+                    _val166 = iprot.readString();
+                    struct.loginProperties.put(_key165, _val166);
                   }
                   iprot.readMapEnd();
                 }
@@ -13197,13 +17021,13 @@
           {
             org.apache.thrift.protocol.TMap _map170 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.loginProperties = new HashMap<String,String>(2*_map170.size);
-            for (int _i171 = 0; _i171 < _map170.size; ++_i171)
+            String _key171;
+            String _val172;
+            for (int _i173 = 0; _i173 < _map170.size; ++_i173)
             {
-              String _key172;
-              String _val173;
-              _key172 = iprot.readString();
-              _val173 = iprot.readString();
-              struct.loginProperties.put(_key172, _val173);
+              _key171 = iprot.readString();
+              _val172 = iprot.readString();
+              struct.loginProperties.put(_key171, _val172);
             }
           }
           struct.setLoginPropertiesIsSet(true);
@@ -13309,7 +17133,7 @@
       AccumuloSecurityException ouch2)
     {
       this();
-      this.success = success;
+      this.success = org.apache.thrift.TBaseHelper.copyBinary(success);
       this.ouch2 = ouch2;
     }
 
@@ -13319,7 +17143,6 @@
     public login_result(login_result other) {
       if (other.isSetSuccess()) {
         this.success = org.apache.thrift.TBaseHelper.copyBinary(other.success);
-;
       }
       if (other.isSetOuch2()) {
         this.ouch2 = new AccumuloSecurityException(other.ouch2);
@@ -13342,16 +17165,16 @@
     }
 
     public ByteBuffer bufferForSuccess() {
-      return success;
+      return org.apache.thrift.TBaseHelper.copyBinary(success);
     }
 
     public login_result setSuccess(byte[] success) {
-      setSuccess(success == null ? (ByteBuffer)null : ByteBuffer.wrap(success));
+      this.success = success == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(success, success.length));
       return this;
     }
 
     public login_result setSuccess(ByteBuffer success) {
-      this.success = success;
+      this.success = org.apache.thrift.TBaseHelper.copyBinary(success);
       return this;
     }
 
@@ -13478,7 +17301,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -13784,7 +17619,7 @@
       String constraintClassName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.constraintClassName = constraintClassName;
     }
@@ -13795,7 +17630,6 @@
     public addConstraint_args(addConstraint_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -13822,16 +17656,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public addConstraint_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public addConstraint_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -14004,7 +17838,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_constraintClassName = true && (isSetConstraintClassName());
+      list.add(present_constraintClassName);
+      if (present_constraintClassName)
+        list.add(constraintClassName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -14531,7 +18382,7 @@
     public Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
-        return Integer.valueOf(getSuccess());
+        return getSuccess();
 
       case OUCH1:
         return getOuch1();
@@ -14619,7 +18470,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -15010,7 +18883,7 @@
       Set<ByteBuffer> splits)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.splits = splits;
     }
@@ -15021,7 +18894,6 @@
     public addSplits_args(addSplits_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -15049,16 +18921,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public addSplits_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public addSplits_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -15246,7 +19118,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_splits = true && (isSetSplits());
+      list.add(present_splits);
+      if (present_splits)
+        list.add(splits);
+
+      return list.hashCode();
     }
 
     @Override
@@ -15327,7 +19216,7 @@
       if (this.splits == null) {
         sb.append("null");
       } else {
-        sb.append(this.splits);
+        org.apache.thrift.TBaseHelper.toString(this.splits, sb);
       }
       first = false;
       sb.append(")");
@@ -15394,11 +19283,11 @@
                 {
                   org.apache.thrift.protocol.TSet _set174 = iprot.readSetBegin();
                   struct.splits = new HashSet<ByteBuffer>(2*_set174.size);
-                  for (int _i175 = 0; _i175 < _set174.size; ++_i175)
+                  ByteBuffer _elem175;
+                  for (int _i176 = 0; _i176 < _set174.size; ++_i176)
                   {
-                    ByteBuffer _elem176;
-                    _elem176 = iprot.readBinary();
-                    struct.splits.add(_elem176);
+                    _elem175 = iprot.readBinary();
+                    struct.splits.add(_elem175);
                   }
                   iprot.readSetEnd();
                 }
@@ -15505,11 +19394,11 @@
           {
             org.apache.thrift.protocol.TSet _set179 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.splits = new HashSet<ByteBuffer>(2*_set179.size);
-            for (int _i180 = 0; _i180 < _set179.size; ++_i180)
+            ByteBuffer _elem180;
+            for (int _i181 = 0; _i181 < _set179.size; ++_i181)
             {
-              ByteBuffer _elem181;
-              _elem181 = iprot.readBinary();
-              struct.splits.add(_elem181);
+              _elem180 = iprot.readBinary();
+              struct.splits.add(_elem180);
             }
           }
           struct.setSplitsIsSet(true);
@@ -15832,7 +19721,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -16192,7 +20098,7 @@
       Set<IteratorScope> scopes)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.setting = setting;
       this.scopes = scopes;
@@ -16204,7 +20110,6 @@
     public attachIterator_args(attachIterator_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -16239,16 +20144,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public attachIterator_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public attachIterator_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -16482,7 +20387,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_setting = true && (isSetSetting());
+      list.add(present_setting);
+      if (present_setting)
+        list.add(setting);
+
+      boolean present_scopes = true && (isSetScopes());
+      list.add(present_scopes);
+      if (present_scopes)
+        list.add(scopes);
+
+      return list.hashCode();
     }
 
     @Override
@@ -16660,11 +20587,11 @@
                 {
                   org.apache.thrift.protocol.TSet _set182 = iprot.readSetBegin();
                   struct.scopes = new HashSet<IteratorScope>(2*_set182.size);
-                  for (int _i183 = 0; _i183 < _set182.size; ++_i183)
+                  IteratorScope _elem183;
+                  for (int _i184 = 0; _i184 < _set182.size; ++_i184)
                   {
-                    IteratorScope _elem184;
-                    _elem184 = IteratorScope.findByValue(iprot.readI32());
-                    struct.scopes.add(_elem184);
+                    _elem183 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                    struct.scopes.add(_elem183);
                   }
                   iprot.readSetEnd();
                 }
@@ -16787,11 +20714,11 @@
           {
             org.apache.thrift.protocol.TSet _set187 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
             struct.scopes = new HashSet<IteratorScope>(2*_set187.size);
-            for (int _i188 = 0; _i188 < _set187.size; ++_i188)
+            IteratorScope _elem188;
+            for (int _i189 = 0; _i189 < _set187.size; ++_i189)
             {
-              IteratorScope _elem189;
-              _elem189 = IteratorScope.findByValue(iprot.readI32());
-              struct.scopes.add(_elem189);
+              _elem188 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+              struct.scopes.add(_elem188);
             }
           }
           struct.setScopesIsSet(true);
@@ -17114,7 +21041,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -17474,7 +21418,7 @@
       Set<IteratorScope> scopes)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.setting = setting;
       this.scopes = scopes;
@@ -17486,7 +21430,6 @@
     public checkIteratorConflicts_args(checkIteratorConflicts_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -17521,16 +21464,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public checkIteratorConflicts_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public checkIteratorConflicts_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -17764,7 +21707,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_setting = true && (isSetSetting());
+      list.add(present_setting);
+      if (present_setting)
+        list.add(setting);
+
+      boolean present_scopes = true && (isSetScopes());
+      list.add(present_scopes);
+      if (present_scopes)
+        list.add(scopes);
+
+      return list.hashCode();
     }
 
     @Override
@@ -17942,11 +21907,11 @@
                 {
                   org.apache.thrift.protocol.TSet _set190 = iprot.readSetBegin();
                   struct.scopes = new HashSet<IteratorScope>(2*_set190.size);
-                  for (int _i191 = 0; _i191 < _set190.size; ++_i191)
+                  IteratorScope _elem191;
+                  for (int _i192 = 0; _i192 < _set190.size; ++_i192)
                   {
-                    IteratorScope _elem192;
-                    _elem192 = IteratorScope.findByValue(iprot.readI32());
-                    struct.scopes.add(_elem192);
+                    _elem191 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                    struct.scopes.add(_elem191);
                   }
                   iprot.readSetEnd();
                 }
@@ -18069,11 +22034,11 @@
           {
             org.apache.thrift.protocol.TSet _set195 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
             struct.scopes = new HashSet<IteratorScope>(2*_set195.size);
-            for (int _i196 = 0; _i196 < _set195.size; ++_i196)
+            IteratorScope _elem196;
+            for (int _i197 = 0; _i197 < _set195.size; ++_i197)
             {
-              IteratorScope _elem197;
-              _elem197 = IteratorScope.findByValue(iprot.readI32());
-              struct.scopes.add(_elem197);
+              _elem196 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+              struct.scopes.add(_elem196);
             }
           }
           struct.setScopesIsSet(true);
@@ -18396,7 +22361,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -18739,7 +22721,7 @@
       String tableName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
     }
 
@@ -18749,7 +22731,6 @@
     public clearLocatorCache_args(clearLocatorCache_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -18772,16 +22753,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public clearLocatorCache_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public clearLocatorCache_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -18908,7 +22889,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -19303,7 +23296,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      return list.hashCode();
     }
 
     @Override
@@ -19597,7 +23597,7 @@
       Set<String> propertiesToExclude)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.newTableName = newTableName;
       this.flush = flush;
@@ -19613,7 +23613,6 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -19653,16 +23652,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public cloneTable_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public cloneTable_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -19891,7 +23890,7 @@
         return getNewTableName();
 
       case FLUSH:
-        return Boolean.valueOf(isFlush());
+        return isFlush();
 
       case PROPERTIES_TO_SET:
         return getPropertiesToSet();
@@ -19998,7 +23997,39 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_newTableName = true && (isSetNewTableName());
+      list.add(present_newTableName);
+      if (present_newTableName)
+        list.add(newTableName);
+
+      boolean present_flush = true;
+      list.add(present_flush);
+      if (present_flush)
+        list.add(flush);
+
+      boolean present_propertiesToSet = true && (isSetPropertiesToSet());
+      list.add(present_propertiesToSet);
+      if (present_propertiesToSet)
+        list.add(propertiesToSet);
+
+      boolean present_propertiesToExclude = true && (isSetPropertiesToExclude());
+      list.add(present_propertiesToExclude);
+      if (present_propertiesToExclude)
+        list.add(propertiesToExclude);
+
+      return list.hashCode();
     }
 
     @Override
@@ -20214,13 +24245,13 @@
                 {
                   org.apache.thrift.protocol.TMap _map198 = iprot.readMapBegin();
                   struct.propertiesToSet = new HashMap<String,String>(2*_map198.size);
-                  for (int _i199 = 0; _i199 < _map198.size; ++_i199)
+                  String _key199;
+                  String _val200;
+                  for (int _i201 = 0; _i201 < _map198.size; ++_i201)
                   {
-                    String _key200;
-                    String _val201;
-                    _key200 = iprot.readString();
-                    _val201 = iprot.readString();
-                    struct.propertiesToSet.put(_key200, _val201);
+                    _key199 = iprot.readString();
+                    _val200 = iprot.readString();
+                    struct.propertiesToSet.put(_key199, _val200);
                   }
                   iprot.readMapEnd();
                 }
@@ -20234,11 +24265,11 @@
                 {
                   org.apache.thrift.protocol.TSet _set202 = iprot.readSetBegin();
                   struct.propertiesToExclude = new HashSet<String>(2*_set202.size);
-                  for (int _i203 = 0; _i203 < _set202.size; ++_i203)
+                  String _elem203;
+                  for (int _i204 = 0; _i204 < _set202.size; ++_i204)
                   {
-                    String _elem204;
-                    _elem204 = iprot.readString();
-                    struct.propertiesToExclude.add(_elem204);
+                    _elem203 = iprot.readString();
+                    struct.propertiesToExclude.add(_elem203);
                   }
                   iprot.readSetEnd();
                 }
@@ -20399,13 +24430,13 @@
           {
             org.apache.thrift.protocol.TMap _map209 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.propertiesToSet = new HashMap<String,String>(2*_map209.size);
-            for (int _i210 = 0; _i210 < _map209.size; ++_i210)
+            String _key210;
+            String _val211;
+            for (int _i212 = 0; _i212 < _map209.size; ++_i212)
             {
-              String _key211;
-              String _val212;
-              _key211 = iprot.readString();
-              _val212 = iprot.readString();
-              struct.propertiesToSet.put(_key211, _val212);
+              _key210 = iprot.readString();
+              _val211 = iprot.readString();
+              struct.propertiesToSet.put(_key210, _val211);
             }
           }
           struct.setPropertiesToSetIsSet(true);
@@ -20414,11 +24445,11 @@
           {
             org.apache.thrift.protocol.TSet _set213 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.propertiesToExclude = new HashSet<String>(2*_set213.size);
-            for (int _i214 = 0; _i214 < _set213.size; ++_i214)
+            String _elem214;
+            for (int _i215 = 0; _i215 < _set213.size; ++_i215)
             {
-              String _elem215;
-              _elem215 = iprot.readString();
-              struct.propertiesToExclude.add(_elem215);
+              _elem214 = iprot.readString();
+              struct.propertiesToExclude.add(_elem214);
             }
           }
           struct.setPropertiesToExcludeIsSet(true);
@@ -20800,7 +24831,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      boolean present_ouch4 = true && (isSetOuch4());
+      list.add(present_ouch4);
+      if (present_ouch4)
+        list.add(ouch4);
+
+      return list.hashCode();
     }
 
     @Override
@@ -21238,10 +25291,10 @@
       CompactionStrategyConfig compactionStrategy)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
-      this.startRow = startRow;
-      this.endRow = endRow;
+      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
+      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       this.iterators = iterators;
       this.flush = flush;
       setFlushIsSet(true);
@@ -21257,18 +25310,15 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
       }
       if (other.isSetStartRow()) {
         this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
-;
       }
       if (other.isSetEndRow()) {
         this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
-;
       }
       if (other.isSetIterators()) {
         List<IteratorSetting> __this__iterators = new ArrayList<IteratorSetting>(other.iterators.size());
@@ -21308,16 +25358,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public compactTable_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public compactTable_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -21366,16 +25416,16 @@
     }
 
     public ByteBuffer bufferForStartRow() {
-      return startRow;
+      return org.apache.thrift.TBaseHelper.copyBinary(startRow);
     }
 
     public compactTable_args setStartRow(byte[] startRow) {
-      setStartRow(startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(startRow));
+      this.startRow = startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(startRow, startRow.length));
       return this;
     }
 
     public compactTable_args setStartRow(ByteBuffer startRow) {
-      this.startRow = startRow;
+      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       return this;
     }
 
@@ -21400,16 +25450,16 @@
     }
 
     public ByteBuffer bufferForEndRow() {
-      return endRow;
+      return org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     public compactTable_args setEndRow(byte[] endRow) {
-      setEndRow(endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(endRow));
+      this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
       return this;
     }
 
     public compactTable_args setEndRow(ByteBuffer endRow) {
-      this.endRow = endRow;
+      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       return this;
     }
 
@@ -21624,10 +25674,10 @@
         return getIterators();
 
       case FLUSH:
-        return Boolean.valueOf(isFlush());
+        return isFlush();
 
       case WAIT:
-        return Boolean.valueOf(isWait());
+        return isWait();
 
       case COMPACTION_STRATEGY:
         return getCompactionStrategy();
@@ -21753,7 +25803,49 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_startRow = true && (isSetStartRow());
+      list.add(present_startRow);
+      if (present_startRow)
+        list.add(startRow);
+
+      boolean present_endRow = true && (isSetEndRow());
+      list.add(present_endRow);
+      if (present_endRow)
+        list.add(endRow);
+
+      boolean present_iterators = true && (isSetIterators());
+      list.add(present_iterators);
+      if (present_iterators)
+        list.add(iterators);
+
+      boolean present_flush = true;
+      list.add(present_flush);
+      if (present_flush)
+        list.add(flush);
+
+      boolean present_wait = true;
+      list.add(present_wait);
+      if (present_wait)
+        list.add(wait);
+
+      boolean present_compactionStrategy = true && (isSetCompactionStrategy());
+      list.add(present_compactionStrategy);
+      if (present_compactionStrategy)
+        list.add(compactionStrategy);
+
+      return list.hashCode();
     }
 
     @Override
@@ -22004,12 +26096,12 @@
                 {
                   org.apache.thrift.protocol.TList _list216 = iprot.readListBegin();
                   struct.iterators = new ArrayList<IteratorSetting>(_list216.size);
-                  for (int _i217 = 0; _i217 < _list216.size; ++_i217)
+                  IteratorSetting _elem217;
+                  for (int _i218 = 0; _i218 < _list216.size; ++_i218)
                   {
-                    IteratorSetting _elem218;
-                    _elem218 = new IteratorSetting();
-                    _elem218.read(iprot);
-                    struct.iterators.add(_elem218);
+                    _elem217 = new IteratorSetting();
+                    _elem217.read(iprot);
+                    struct.iterators.add(_elem217);
                   }
                   iprot.readListEnd();
                 }
@@ -22200,12 +26292,12 @@
           {
             org.apache.thrift.protocol.TList _list221 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
             struct.iterators = new ArrayList<IteratorSetting>(_list221.size);
-            for (int _i222 = 0; _i222 < _list221.size; ++_i222)
+            IteratorSetting _elem222;
+            for (int _i223 = 0; _i223 < _list221.size; ++_i223)
             {
-              IteratorSetting _elem223;
-              _elem223 = new IteratorSetting();
-              _elem223.read(iprot);
-              struct.iterators.add(_elem223);
+              _elem222 = new IteratorSetting();
+              _elem222.read(iprot);
+              struct.iterators.add(_elem222);
             }
           }
           struct.setIteratorsIsSet(true);
@@ -22541,7 +26633,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -22884,7 +26993,7 @@
       String tableName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
     }
 
@@ -22894,7 +27003,6 @@
     public cancelCompaction_args(cancelCompaction_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -22917,16 +27025,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public cancelCompaction_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public cancelCompaction_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -23053,7 +27161,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -23566,7 +27686,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -23935,7 +28072,7 @@
       TimeType type)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.versioningIter = versioningIter;
       setVersioningIterIsSet(true);
@@ -23949,7 +28086,6 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -23979,16 +28115,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createTable_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public createTable_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -24132,7 +28268,7 @@
         return getTableName();
 
       case VERSIONING_ITER:
-        return Boolean.valueOf(isVersioningIter());
+        return isVersioningIter();
 
       case TYPE:
         return getType();
@@ -24214,7 +28350,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_versioningIter = true;
+      list.add(present_versioningIter);
+      if (present_versioningIter)
+        list.add(versioningIter);
+
+      boolean present_type = true && (isSetType());
+      list.add(present_type);
+      if (present_type)
+        list.add(type.getValue());
+
+      return list.hashCode();
     }
 
     @Override
@@ -24383,7 +28541,7 @@
               break;
             case 4: // TYPE
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-                struct.type = TimeType.findByValue(iprot.readI32());
+                struct.type = org.apache.accumulo.proxy.thrift.TimeType.findByValue(iprot.readI32());
                 struct.setTypeIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -24484,7 +28642,7 @@
           struct.setVersioningIterIsSet(true);
         }
         if (incoming.get(3)) {
-          struct.type = TimeType.findByValue(iprot.readI32());
+          struct.type = org.apache.accumulo.proxy.thrift.TimeType.findByValue(iprot.readI32());
           struct.setTypeIsSet(true);
         }
       }
@@ -24805,7 +28963,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -25148,7 +29323,7 @@
       String tableName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
     }
 
@@ -25158,7 +29333,6 @@
     public deleteTable_args(deleteTable_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -25181,16 +29355,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public deleteTable_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public deleteTable_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -25317,7 +29491,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -25830,7 +30016,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -26189,10 +30392,10 @@
       ByteBuffer endRow)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
-      this.startRow = startRow;
-      this.endRow = endRow;
+      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
+      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     /**
@@ -26201,18 +30404,15 @@
     public deleteRows_args(deleteRows_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
       }
       if (other.isSetStartRow()) {
         this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
-;
       }
       if (other.isSetEndRow()) {
         this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
-;
       }
     }
 
@@ -26234,16 +30434,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public deleteRows_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public deleteRows_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -26292,16 +30492,16 @@
     }
 
     public ByteBuffer bufferForStartRow() {
-      return startRow;
+      return org.apache.thrift.TBaseHelper.copyBinary(startRow);
     }
 
     public deleteRows_args setStartRow(byte[] startRow) {
-      setStartRow(startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(startRow));
+      this.startRow = startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(startRow, startRow.length));
       return this;
     }
 
     public deleteRows_args setStartRow(ByteBuffer startRow) {
-      this.startRow = startRow;
+      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       return this;
     }
 
@@ -26326,16 +30526,16 @@
     }
 
     public ByteBuffer bufferForEndRow() {
-      return endRow;
+      return org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     public deleteRows_args setEndRow(byte[] endRow) {
-      setEndRow(endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(endRow));
+      this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
       return this;
     }
 
     public deleteRows_args setEndRow(ByteBuffer endRow) {
-      this.endRow = endRow;
+      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       return this;
     }
 
@@ -26482,7 +30682,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_startRow = true && (isSetStartRow());
+      list.add(present_startRow);
+      if (present_startRow)
+        list.add(startRow);
+
+      boolean present_endRow = true && (isSetEndRow());
+      list.add(present_endRow);
+      if (present_endRow)
+        list.add(endRow);
+
+      return list.hashCode();
     }
 
     @Override
@@ -27077,7 +31299,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -27428,7 +31667,7 @@
       String exportDir)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.exportDir = exportDir;
     }
@@ -27439,7 +31678,6 @@
     public exportTable_args(exportTable_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -27466,16 +31704,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public exportTable_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public exportTable_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -27648,7 +31886,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_exportDir = true && (isSetExportDir());
+      list.add(present_exportDir);
+      if (present_exportDir)
+        list.add(exportDir);
+
+      return list.hashCode();
     }
 
     @Override
@@ -28202,7 +32457,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -28571,10 +32843,10 @@
       boolean wait)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
-      this.startRow = startRow;
-      this.endRow = endRow;
+      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
+      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       this.wait = wait;
       setWaitIsSet(true);
     }
@@ -28586,18 +32858,15 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
       }
       if (other.isSetStartRow()) {
         this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
-;
       }
       if (other.isSetEndRow()) {
         this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
-;
       }
       this.wait = other.wait;
     }
@@ -28622,16 +32891,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public flushTable_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public flushTable_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -28680,16 +32949,16 @@
     }
 
     public ByteBuffer bufferForStartRow() {
-      return startRow;
+      return org.apache.thrift.TBaseHelper.copyBinary(startRow);
     }
 
     public flushTable_args setStartRow(byte[] startRow) {
-      setStartRow(startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(startRow));
+      this.startRow = startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(startRow, startRow.length));
       return this;
     }
 
     public flushTable_args setStartRow(ByteBuffer startRow) {
-      this.startRow = startRow;
+      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       return this;
     }
 
@@ -28714,16 +32983,16 @@
     }
 
     public ByteBuffer bufferForEndRow() {
-      return endRow;
+      return org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     public flushTable_args setEndRow(byte[] endRow) {
-      setEndRow(endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(endRow));
+      this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
       return this;
     }
 
     public flushTable_args setEndRow(ByteBuffer endRow) {
-      this.endRow = endRow;
+      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       return this;
     }
 
@@ -28825,7 +33094,7 @@
         return getEndRow();
 
       case WAIT:
-        return Boolean.valueOf(isWait());
+        return isWait();
 
       }
       throw new IllegalStateException();
@@ -28915,7 +33184,34 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_startRow = true && (isSetStartRow());
+      list.add(present_startRow);
+      if (present_startRow)
+        list.add(startRow);
+
+      boolean present_endRow = true && (isSetEndRow());
+      list.add(present_endRow);
+      if (present_endRow)
+        list.add(endRow);
+
+      boolean present_wait = true;
+      list.add(present_wait);
+      if (present_wait)
+        list.add(wait);
+
+      return list.hashCode();
     }
 
     @Override
@@ -29547,7 +33843,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -29891,7 +34204,7 @@
       Set<String> tables)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tables = tables;
     }
 
@@ -29901,7 +34214,6 @@
     public getDiskUsage_args(getDiskUsage_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTables()) {
         Set<String> __this__tables = new HashSet<String>(other.tables);
@@ -29925,16 +34237,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getDiskUsage_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getDiskUsage_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -30076,7 +34388,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tables = true && (isSetTables());
+      list.add(present_tables);
+      if (present_tables)
+        list.add(tables);
+
+      return list.hashCode();
     }
 
     @Override
@@ -30198,11 +34522,11 @@
                 {
                   org.apache.thrift.protocol.TSet _set224 = iprot.readSetBegin();
                   struct.tables = new HashSet<String>(2*_set224.size);
-                  for (int _i225 = 0; _i225 < _set224.size; ++_i225)
+                  String _elem225;
+                  for (int _i226 = 0; _i226 < _set224.size; ++_i226)
                   {
-                    String _elem226;
-                    _elem226 = iprot.readString();
-                    struct.tables.add(_elem226);
+                    _elem225 = iprot.readString();
+                    struct.tables.add(_elem225);
                   }
                   iprot.readSetEnd();
                 }
@@ -30294,11 +34618,11 @@
           {
             org.apache.thrift.protocol.TSet _set229 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.tables = new HashSet<String>(2*_set229.size);
-            for (int _i230 = 0; _i230 < _set229.size; ++_i230)
+            String _elem230;
+            for (int _i231 = 0; _i231 < _set229.size; ++_i231)
             {
-              String _elem231;
-              _elem231 = iprot.readString();
-              struct.tables.add(_elem231);
+              _elem230 = iprot.readString();
+              struct.tables.add(_elem230);
             }
           }
           struct.setTablesIsSet(true);
@@ -30700,7 +35024,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -30850,12 +35196,12 @@
                 {
                   org.apache.thrift.protocol.TList _list232 = iprot.readListBegin();
                   struct.success = new ArrayList<DiskUsage>(_list232.size);
-                  for (int _i233 = 0; _i233 < _list232.size; ++_i233)
+                  DiskUsage _elem233;
+                  for (int _i234 = 0; _i234 < _list232.size; ++_i234)
                   {
-                    DiskUsage _elem234;
-                    _elem234 = new DiskUsage();
-                    _elem234.read(iprot);
-                    struct.success.add(_elem234);
+                    _elem233 = new DiskUsage();
+                    _elem233.read(iprot);
+                    struct.success.add(_elem233);
                   }
                   iprot.readListEnd();
                 }
@@ -30992,12 +35338,12 @@
           {
             org.apache.thrift.protocol.TList _list237 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
             struct.success = new ArrayList<DiskUsage>(_list237.size);
-            for (int _i238 = 0; _i238 < _list237.size; ++_i238)
+            DiskUsage _elem238;
+            for (int _i239 = 0; _i239 < _list237.size; ++_i239)
             {
-              DiskUsage _elem239;
-              _elem239 = new DiskUsage();
-              _elem239.read(iprot);
-              struct.success.add(_elem239);
+              _elem238 = new DiskUsage();
+              _elem238.read(iprot);
+              struct.success.add(_elem238);
             }
           }
           struct.setSuccessIsSet(true);
@@ -31118,7 +35464,7 @@
       String tableName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
     }
 
@@ -31128,7 +35474,6 @@
     public getLocalityGroups_args(getLocalityGroups_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -31151,16 +35496,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getLocalityGroups_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getLocalityGroups_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -31287,7 +35632,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -31885,7 +36242,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -32035,23 +36414,23 @@
                 {
                   org.apache.thrift.protocol.TMap _map240 = iprot.readMapBegin();
                   struct.success = new HashMap<String,Set<String>>(2*_map240.size);
-                  for (int _i241 = 0; _i241 < _map240.size; ++_i241)
+                  String _key241;
+                  Set<String> _val242;
+                  for (int _i243 = 0; _i243 < _map240.size; ++_i243)
                   {
-                    String _key242;
-                    Set<String> _val243;
-                    _key242 = iprot.readString();
+                    _key241 = iprot.readString();
                     {
                       org.apache.thrift.protocol.TSet _set244 = iprot.readSetBegin();
-                      _val243 = new HashSet<String>(2*_set244.size);
-                      for (int _i245 = 0; _i245 < _set244.size; ++_i245)
+                      _val242 = new HashSet<String>(2*_set244.size);
+                      String _elem245;
+                      for (int _i246 = 0; _i246 < _set244.size; ++_i246)
                       {
-                        String _elem246;
-                        _elem246 = iprot.readString();
-                        _val243.add(_elem246);
+                        _elem245 = iprot.readString();
+                        _val242.add(_elem245);
                       }
                       iprot.readSetEnd();
                     }
-                    struct.success.put(_key242, _val243);
+                    struct.success.put(_key241, _val242);
                   }
                   iprot.readMapEnd();
                 }
@@ -32203,22 +36582,22 @@
           {
             org.apache.thrift.protocol.TMap _map251 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, iprot.readI32());
             struct.success = new HashMap<String,Set<String>>(2*_map251.size);
-            for (int _i252 = 0; _i252 < _map251.size; ++_i252)
+            String _key252;
+            Set<String> _val253;
+            for (int _i254 = 0; _i254 < _map251.size; ++_i254)
             {
-              String _key253;
-              Set<String> _val254;
-              _key253 = iprot.readString();
+              _key252 = iprot.readString();
               {
                 org.apache.thrift.protocol.TSet _set255 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
-                _val254 = new HashSet<String>(2*_set255.size);
-                for (int _i256 = 0; _i256 < _set255.size; ++_i256)
+                _val253 = new HashSet<String>(2*_set255.size);
+                String _elem256;
+                for (int _i257 = 0; _i257 < _set255.size; ++_i257)
                 {
-                  String _elem257;
-                  _elem257 = iprot.readString();
-                  _val254.add(_elem257);
+                  _elem256 = iprot.readString();
+                  _val253.add(_elem256);
                 }
               }
-              struct.success.put(_key253, _val254);
+              struct.success.put(_key252, _val253);
             }
           }
           struct.setSuccessIsSet(true);
@@ -32363,7 +36742,7 @@
       IteratorScope scope)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.iteratorName = iteratorName;
       this.scope = scope;
@@ -32375,7 +36754,6 @@
     public getIteratorSetting_args(getIteratorSetting_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -32406,16 +36784,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getIteratorSetting_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getIteratorSetting_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -32642,7 +37020,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_iteratorName = true && (isSetIteratorName());
+      list.add(present_iteratorName);
+      if (present_iteratorName)
+        list.add(iteratorName);
+
+      boolean present_scope = true && (isSetScope());
+      list.add(present_scope);
+      if (present_scope)
+        list.add(scope.getValue());
+
+      return list.hashCode();
     }
 
     @Override
@@ -32813,7 +37213,7 @@
               break;
             case 4: // SCOPE
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-                struct.scope = IteratorScope.findByValue(iprot.readI32());
+                struct.scope = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
                 struct.setScopeIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -32916,7 +37316,7 @@
           struct.setIteratorNameIsSet(true);
         }
         if (incoming.get(3)) {
-          struct.scope = IteratorScope.findByValue(iprot.readI32());
+          struct.scope = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
           struct.setScopeIsSet(true);
         }
       }
@@ -33296,7 +37696,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -33729,13 +38151,13 @@
       boolean endInclusive)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.auths = auths;
-      this.startRow = startRow;
+      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       this.startInclusive = startInclusive;
       setStartInclusiveIsSet(true);
-      this.endRow = endRow;
+      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       this.endInclusive = endInclusive;
       setEndInclusiveIsSet(true);
     }
@@ -33747,7 +38169,6 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -33758,12 +38179,10 @@
       }
       if (other.isSetStartRow()) {
         this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
-;
       }
       this.startInclusive = other.startInclusive;
       if (other.isSetEndRow()) {
         this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
-;
       }
       this.endInclusive = other.endInclusive;
     }
@@ -33791,16 +38210,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getMaxRow_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getMaxRow_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -33888,16 +38307,16 @@
     }
 
     public ByteBuffer bufferForStartRow() {
-      return startRow;
+      return org.apache.thrift.TBaseHelper.copyBinary(startRow);
     }
 
     public getMaxRow_args setStartRow(byte[] startRow) {
-      setStartRow(startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(startRow));
+      this.startRow = startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(startRow, startRow.length));
       return this;
     }
 
     public getMaxRow_args setStartRow(ByteBuffer startRow) {
-      this.startRow = startRow;
+      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       return this;
     }
 
@@ -33945,16 +38364,16 @@
     }
 
     public ByteBuffer bufferForEndRow() {
-      return endRow;
+      return org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     public getMaxRow_args setEndRow(byte[] endRow) {
-      setEndRow(endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(endRow));
+      this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
       return this;
     }
 
     public getMaxRow_args setEndRow(ByteBuffer endRow) {
-      this.endRow = endRow;
+      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       return this;
     }
 
@@ -34072,13 +38491,13 @@
         return getStartRow();
 
       case START_INCLUSIVE:
-        return Boolean.valueOf(isStartInclusive());
+        return isStartInclusive();
 
       case END_ROW:
         return getEndRow();
 
       case END_INCLUSIVE:
-        return Boolean.valueOf(isEndInclusive());
+        return isEndInclusive();
 
       }
       throw new IllegalStateException();
@@ -34190,7 +38609,44 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_auths = true && (isSetAuths());
+      list.add(present_auths);
+      if (present_auths)
+        list.add(auths);
+
+      boolean present_startRow = true && (isSetStartRow());
+      list.add(present_startRow);
+      if (present_startRow)
+        list.add(startRow);
+
+      boolean present_startInclusive = true;
+      list.add(present_startInclusive);
+      if (present_startInclusive)
+        list.add(startInclusive);
+
+      boolean present_endRow = true && (isSetEndRow());
+      list.add(present_endRow);
+      if (present_endRow)
+        list.add(endRow);
+
+      boolean present_endInclusive = true;
+      list.add(present_endInclusive);
+      if (present_endInclusive)
+        list.add(endInclusive);
+
+      return list.hashCode();
     }
 
     @Override
@@ -34311,7 +38767,7 @@
       if (this.auths == null) {
         sb.append("null");
       } else {
-        sb.append(this.auths);
+        org.apache.thrift.TBaseHelper.toString(this.auths, sb);
       }
       first = false;
       if (!first) sb.append(", ");
@@ -34404,11 +38860,11 @@
                 {
                   org.apache.thrift.protocol.TSet _set258 = iprot.readSetBegin();
                   struct.auths = new HashSet<ByteBuffer>(2*_set258.size);
-                  for (int _i259 = 0; _i259 < _set258.size; ++_i259)
+                  ByteBuffer _elem259;
+                  for (int _i260 = 0; _i260 < _set258.size; ++_i260)
                   {
-                    ByteBuffer _elem260;
-                    _elem260 = iprot.readBinary();
-                    struct.auths.add(_elem260);
+                    _elem259 = iprot.readBinary();
+                    struct.auths.add(_elem259);
                   }
                   iprot.readSetEnd();
                 }
@@ -34587,11 +39043,11 @@
           {
             org.apache.thrift.protocol.TSet _set263 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.auths = new HashSet<ByteBuffer>(2*_set263.size);
-            for (int _i264 = 0; _i264 < _set263.size; ++_i264)
+            ByteBuffer _elem264;
+            for (int _i265 = 0; _i265 < _set263.size; ++_i265)
             {
-              ByteBuffer _elem265;
-              _elem265 = iprot.readBinary();
-              struct.auths.add(_elem265);
+              _elem264 = iprot.readBinary();
+              struct.auths.add(_elem264);
             }
           }
           struct.setAuthsIsSet(true);
@@ -34729,7 +39185,7 @@
       TableNotFoundException ouch3)
     {
       this();
-      this.success = success;
+      this.success = org.apache.thrift.TBaseHelper.copyBinary(success);
       this.ouch1 = ouch1;
       this.ouch2 = ouch2;
       this.ouch3 = ouch3;
@@ -34741,7 +39197,6 @@
     public getMaxRow_result(getMaxRow_result other) {
       if (other.isSetSuccess()) {
         this.success = org.apache.thrift.TBaseHelper.copyBinary(other.success);
-;
       }
       if (other.isSetOuch1()) {
         this.ouch1 = new AccumuloException(other.ouch1);
@@ -34772,16 +39227,16 @@
     }
 
     public ByteBuffer bufferForSuccess() {
-      return success;
+      return org.apache.thrift.TBaseHelper.copyBinary(success);
     }
 
     public getMaxRow_result setSuccess(byte[] success) {
-      setSuccess(success == null ? (ByteBuffer)null : ByteBuffer.wrap(success));
+      this.success = success == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(success, success.length));
       return this;
     }
 
     public getMaxRow_result setSuccess(ByteBuffer success) {
-      this.success = success;
+      this.success = org.apache.thrift.TBaseHelper.copyBinary(success);
       return this;
     }
 
@@ -35000,7 +39455,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -35384,7 +39861,7 @@
       String tableName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
     }
 
@@ -35394,7 +39871,6 @@
     public getTableProperties_args(getTableProperties_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -35417,16 +39893,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getTableProperties_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getTableProperties_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -35553,7 +40029,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -36139,7 +40627,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -36289,13 +40799,13 @@
                 {
                   org.apache.thrift.protocol.TMap _map266 = iprot.readMapBegin();
                   struct.success = new HashMap<String,String>(2*_map266.size);
-                  for (int _i267 = 0; _i267 < _map266.size; ++_i267)
+                  String _key267;
+                  String _val268;
+                  for (int _i269 = 0; _i269 < _map266.size; ++_i269)
                   {
-                    String _key268;
-                    String _val269;
-                    _key268 = iprot.readString();
-                    _val269 = iprot.readString();
-                    struct.success.put(_key268, _val269);
+                    _key267 = iprot.readString();
+                    _val268 = iprot.readString();
+                    struct.success.put(_key267, _val268);
                   }
                   iprot.readMapEnd();
                 }
@@ -36434,13 +40944,13 @@
           {
             org.apache.thrift.protocol.TMap _map272 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.success = new HashMap<String,String>(2*_map272.size);
-            for (int _i273 = 0; _i273 < _map272.size; ++_i273)
+            String _key273;
+            String _val274;
+            for (int _i275 = 0; _i275 < _map272.size; ++_i275)
             {
-              String _key274;
-              String _val275;
-              _key274 = iprot.readString();
-              _val275 = iprot.readString();
-              struct.success.put(_key274, _val275);
+              _key273 = iprot.readString();
+              _val274 = iprot.readString();
+              struct.success.put(_key273, _val274);
             }
           }
           struct.setSuccessIsSet(true);
@@ -36587,7 +41097,7 @@
       boolean setTime)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.importDir = importDir;
       this.failureDir = failureDir;
@@ -36602,7 +41112,6 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -36636,16 +41145,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public importDirectory_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public importDirectory_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -36819,7 +41328,7 @@
         return getFailureDir();
 
       case SET_TIME:
-        return Boolean.valueOf(isSetTime());
+        return isSetTime();
 
       }
       throw new IllegalStateException();
@@ -36909,7 +41418,34 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_importDir = true && (isSetImportDir());
+      list.add(present_importDir);
+      if (present_importDir)
+        list.add(importDir);
+
+      boolean present_failureDir = true && (isSetFailureDir());
+      list.add(present_failureDir);
+      if (present_failureDir)
+        list.add(failureDir);
+
+      boolean present_setTime = true;
+      list.add(present_setTime);
+      if (present_setTime)
+        list.add(setTime);
+
+      return list.hashCode();
     }
 
     @Override
@@ -37541,7 +42077,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      boolean present_ouch4 = true && (isSetOuch4());
+      list.add(present_ouch4);
+      if (present_ouch4)
+        list.add(ouch4);
+
+      return list.hashCode();
     }
 
     @Override
@@ -37892,7 +42445,7 @@
       String importDir)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.importDir = importDir;
     }
@@ -37903,7 +42456,6 @@
     public importTable_args(importTable_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -37930,16 +42482,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public importTable_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public importTable_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -38112,7 +42664,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_importDir = true && (isSetImportDir());
+      list.add(present_importDir);
+      if (present_importDir)
+        list.add(importDir);
+
+      return list.hashCode();
     }
 
     @Override
@@ -38666,7 +43235,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -39019,7 +43605,7 @@
       int maxSplits)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.maxSplits = maxSplits;
       setMaxSplitsIsSet(true);
@@ -39032,7 +43618,6 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -39058,16 +43643,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public listSplits_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public listSplits_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -39171,7 +43756,7 @@
         return getTableName();
 
       case MAX_SPLITS:
-        return Integer.valueOf(getMaxSplits());
+        return getMaxSplits();
 
       }
       throw new IllegalStateException();
@@ -39239,7 +43824,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_maxSplits = true;
+      list.add(present_maxSplits);
+      if (present_maxSplits)
+        list.add(maxSplits);
+
+      return list.hashCode();
     }
 
     @Override
@@ -39865,7 +44467,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -39940,7 +44564,7 @@
       if (this.success == null) {
         sb.append("null");
       } else {
-        sb.append(this.success);
+        org.apache.thrift.TBaseHelper.toString(this.success, sb);
       }
       first = false;
       if (!first) sb.append(", ");
@@ -40015,11 +44639,11 @@
                 {
                   org.apache.thrift.protocol.TList _list276 = iprot.readListBegin();
                   struct.success = new ArrayList<ByteBuffer>(_list276.size);
-                  for (int _i277 = 0; _i277 < _list276.size; ++_i277)
+                  ByteBuffer _elem277;
+                  for (int _i278 = 0; _i278 < _list276.size; ++_i278)
                   {
-                    ByteBuffer _elem278;
-                    _elem278 = iprot.readBinary();
-                    struct.success.add(_elem278);
+                    _elem277 = iprot.readBinary();
+                    struct.success.add(_elem277);
                   }
                   iprot.readListEnd();
                 }
@@ -40156,11 +44780,11 @@
           {
             org.apache.thrift.protocol.TList _list281 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.success = new ArrayList<ByteBuffer>(_list281.size);
-            for (int _i282 = 0; _i282 < _list281.size; ++_i282)
+            ByteBuffer _elem282;
+            for (int _i283 = 0; _i283 < _list281.size; ++_i283)
             {
-              ByteBuffer _elem283;
-              _elem283 = iprot.readBinary();
-              struct.success.add(_elem283);
+              _elem282 = iprot.readBinary();
+              struct.success.add(_elem282);
             }
           }
           struct.setSuccessIsSet(true);
@@ -40273,7 +44897,7 @@
       ByteBuffer login)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     /**
@@ -40282,7 +44906,6 @@
     public listTables_args(listTables_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
     }
 
@@ -40301,16 +44924,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public listTables_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public listTables_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -40391,7 +45014,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      return list.hashCode();
     }
 
     @Override
@@ -40762,7 +45392,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      return list.hashCode();
     }
 
     @Override
@@ -40858,11 +45495,11 @@
                 {
                   org.apache.thrift.protocol.TSet _set284 = iprot.readSetBegin();
                   struct.success = new HashSet<String>(2*_set284.size);
-                  for (int _i285 = 0; _i285 < _set284.size; ++_i285)
+                  String _elem285;
+                  for (int _i286 = 0; _i286 < _set284.size; ++_i286)
                   {
-                    String _elem286;
-                    _elem286 = iprot.readString();
-                    struct.success.add(_elem286);
+                    _elem285 = iprot.readString();
+                    struct.success.add(_elem285);
                   }
                   iprot.readSetEnd();
                 }
@@ -40939,11 +45576,11 @@
           {
             org.apache.thrift.protocol.TSet _set289 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.success = new HashSet<String>(2*_set289.size);
-            for (int _i290 = 0; _i290 < _set289.size; ++_i290)
+            String _elem290;
+            for (int _i291 = 0; _i291 < _set289.size; ++_i291)
             {
-              String _elem291;
-              _elem291 = iprot.readString();
-              struct.success.add(_elem291);
+              _elem290 = iprot.readString();
+              struct.success.add(_elem290);
             }
           }
           struct.setSuccessIsSet(true);
@@ -41049,7 +45686,7 @@
       String tableName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
     }
 
@@ -41059,7 +45696,6 @@
     public listIterators_args(listIterators_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -41082,16 +45718,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public listIterators_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public listIterators_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -41218,7 +45854,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -41819,7 +46467,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -41969,23 +46639,23 @@
                 {
                   org.apache.thrift.protocol.TMap _map292 = iprot.readMapBegin();
                   struct.success = new HashMap<String,Set<IteratorScope>>(2*_map292.size);
-                  for (int _i293 = 0; _i293 < _map292.size; ++_i293)
+                  String _key293;
+                  Set<IteratorScope> _val294;
+                  for (int _i295 = 0; _i295 < _map292.size; ++_i295)
                   {
-                    String _key294;
-                    Set<IteratorScope> _val295;
-                    _key294 = iprot.readString();
+                    _key293 = iprot.readString();
                     {
                       org.apache.thrift.protocol.TSet _set296 = iprot.readSetBegin();
-                      _val295 = new HashSet<IteratorScope>(2*_set296.size);
-                      for (int _i297 = 0; _i297 < _set296.size; ++_i297)
+                      _val294 = new HashSet<IteratorScope>(2*_set296.size);
+                      IteratorScope _elem297;
+                      for (int _i298 = 0; _i298 < _set296.size; ++_i298)
                       {
-                        IteratorScope _elem298;
-                        _elem298 = IteratorScope.findByValue(iprot.readI32());
-                        _val295.add(_elem298);
+                        _elem297 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                        _val294.add(_elem297);
                       }
                       iprot.readSetEnd();
                     }
-                    struct.success.put(_key294, _val295);
+                    struct.success.put(_key293, _val294);
                   }
                   iprot.readMapEnd();
                 }
@@ -42137,22 +46807,22 @@
           {
             org.apache.thrift.protocol.TMap _map303 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, iprot.readI32());
             struct.success = new HashMap<String,Set<IteratorScope>>(2*_map303.size);
-            for (int _i304 = 0; _i304 < _map303.size; ++_i304)
+            String _key304;
+            Set<IteratorScope> _val305;
+            for (int _i306 = 0; _i306 < _map303.size; ++_i306)
             {
-              String _key305;
-              Set<IteratorScope> _val306;
-              _key305 = iprot.readString();
+              _key304 = iprot.readString();
               {
                 org.apache.thrift.protocol.TSet _set307 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
-                _val306 = new HashSet<IteratorScope>(2*_set307.size);
-                for (int _i308 = 0; _i308 < _set307.size; ++_i308)
+                _val305 = new HashSet<IteratorScope>(2*_set307.size);
+                IteratorScope _elem308;
+                for (int _i309 = 0; _i309 < _set307.size; ++_i309)
                 {
-                  IteratorScope _elem309;
-                  _elem309 = IteratorScope.findByValue(iprot.readI32());
-                  _val306.add(_elem309);
+                  _elem308 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                  _val305.add(_elem308);
                 }
               }
-              struct.success.put(_key305, _val306);
+              struct.success.put(_key304, _val305);
             }
           }
           struct.setSuccessIsSet(true);
@@ -42273,7 +46943,7 @@
       String tableName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
     }
 
@@ -42283,7 +46953,6 @@
     public listConstraints_args(listConstraints_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -42306,16 +46975,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public listConstraints_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public listConstraints_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -42442,7 +47111,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -43028,7 +47709,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -43178,13 +47881,13 @@
                 {
                   org.apache.thrift.protocol.TMap _map310 = iprot.readMapBegin();
                   struct.success = new HashMap<String,Integer>(2*_map310.size);
-                  for (int _i311 = 0; _i311 < _map310.size; ++_i311)
+                  String _key311;
+                  int _val312;
+                  for (int _i313 = 0; _i313 < _map310.size; ++_i313)
                   {
-                    String _key312;
-                    int _val313;
-                    _key312 = iprot.readString();
-                    _val313 = iprot.readI32();
-                    struct.success.put(_key312, _val313);
+                    _key311 = iprot.readString();
+                    _val312 = iprot.readI32();
+                    struct.success.put(_key311, _val312);
                   }
                   iprot.readMapEnd();
                 }
@@ -43323,13 +48026,13 @@
           {
             org.apache.thrift.protocol.TMap _map316 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, iprot.readI32());
             struct.success = new HashMap<String,Integer>(2*_map316.size);
-            for (int _i317 = 0; _i317 < _map316.size; ++_i317)
+            String _key317;
+            int _val318;
+            for (int _i319 = 0; _i319 < _map316.size; ++_i319)
             {
-              String _key318;
-              int _val319;
-              _key318 = iprot.readString();
-              _val319 = iprot.readI32();
-              struct.success.put(_key318, _val319);
+              _key317 = iprot.readString();
+              _val318 = iprot.readI32();
+              struct.success.put(_key317, _val318);
             }
           }
           struct.setSuccessIsSet(true);
@@ -43466,10 +48169,10 @@
       ByteBuffer endRow)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
-      this.startRow = startRow;
-      this.endRow = endRow;
+      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
+      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     /**
@@ -43478,18 +48181,15 @@
     public mergeTablets_args(mergeTablets_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
       }
       if (other.isSetStartRow()) {
         this.startRow = org.apache.thrift.TBaseHelper.copyBinary(other.startRow);
-;
       }
       if (other.isSetEndRow()) {
         this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
-;
       }
     }
 
@@ -43511,16 +48211,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public mergeTablets_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public mergeTablets_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -43569,16 +48269,16 @@
     }
 
     public ByteBuffer bufferForStartRow() {
-      return startRow;
+      return org.apache.thrift.TBaseHelper.copyBinary(startRow);
     }
 
     public mergeTablets_args setStartRow(byte[] startRow) {
-      setStartRow(startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(startRow));
+      this.startRow = startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(startRow, startRow.length));
       return this;
     }
 
     public mergeTablets_args setStartRow(ByteBuffer startRow) {
-      this.startRow = startRow;
+      this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       return this;
     }
 
@@ -43603,16 +48303,16 @@
     }
 
     public ByteBuffer bufferForEndRow() {
-      return endRow;
+      return org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     public mergeTablets_args setEndRow(byte[] endRow) {
-      setEndRow(endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(endRow));
+      this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
       return this;
     }
 
     public mergeTablets_args setEndRow(ByteBuffer endRow) {
-      this.endRow = endRow;
+      this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       return this;
     }
 
@@ -43759,7 +48459,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_startRow = true && (isSetStartRow());
+      list.add(present_startRow);
+      if (present_startRow)
+        list.add(startRow);
+
+      boolean present_endRow = true && (isSetEndRow());
+      list.add(present_endRow);
+      if (present_endRow)
+        list.add(endRow);
+
+      return list.hashCode();
     }
 
     @Override
@@ -44354,7 +49076,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -44709,7 +49448,7 @@
       boolean wait)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.wait = wait;
       setWaitIsSet(true);
@@ -44722,7 +49461,6 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -44748,16 +49486,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public offlineTable_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public offlineTable_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -44861,7 +49599,7 @@
         return getTableName();
 
       case WAIT:
-        return Boolean.valueOf(isWait());
+        return isWait();
 
       }
       throw new IllegalStateException();
@@ -44929,7 +49667,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_wait = true;
+      list.add(present_wait);
+      if (present_wait)
+        list.add(wait);
+
+      return list.hashCode();
     }
 
     @Override
@@ -45479,7 +50234,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -45834,7 +50606,7 @@
       boolean wait)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.wait = wait;
       setWaitIsSet(true);
@@ -45847,7 +50619,6 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -45873,16 +50644,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public onlineTable_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public onlineTable_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -45986,7 +50757,7 @@
         return getTableName();
 
       case WAIT:
-        return Boolean.valueOf(isWait());
+        return isWait();
 
       }
       throw new IllegalStateException();
@@ -46054,7 +50825,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_wait = true;
+      list.add(present_wait);
+      if (present_wait)
+        list.add(wait);
+
+      return list.hashCode();
     }
 
     @Override
@@ -46604,7 +51392,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -46957,7 +51762,7 @@
       int constraint)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.constraint = constraint;
       setConstraintIsSet(true);
@@ -46970,7 +51775,6 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -46996,16 +51800,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public removeConstraint_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public removeConstraint_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -47109,7 +51913,7 @@
         return getTableName();
 
       case CONSTRAINT:
-        return Integer.valueOf(getConstraint());
+        return getConstraint();
 
       }
       throw new IllegalStateException();
@@ -47177,7 +51981,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_constraint = true;
+      list.add(present_constraint);
+      if (present_constraint)
+        list.add(constraint);
+
+      return list.hashCode();
     }
 
     @Override
@@ -47727,7 +52548,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -48087,7 +52925,7 @@
       Set<IteratorScope> scopes)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.iterName = iterName;
       this.scopes = scopes;
@@ -48099,7 +52937,6 @@
     public removeIterator_args(removeIterator_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -48134,16 +52971,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public removeIterator_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public removeIterator_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -48377,7 +53214,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_iterName = true && (isSetIterName());
+      list.add(present_iterName);
+      if (present_iterName)
+        list.add(iterName);
+
+      boolean present_scopes = true && (isSetScopes());
+      list.add(present_scopes);
+      if (present_scopes)
+        list.add(scopes);
+
+      return list.hashCode();
     }
 
     @Override
@@ -48551,11 +53410,11 @@
                 {
                   org.apache.thrift.protocol.TSet _set320 = iprot.readSetBegin();
                   struct.scopes = new HashSet<IteratorScope>(2*_set320.size);
-                  for (int _i321 = 0; _i321 < _set320.size; ++_i321)
+                  IteratorScope _elem321;
+                  for (int _i322 = 0; _i322 < _set320.size; ++_i322)
                   {
-                    IteratorScope _elem322;
-                    _elem322 = IteratorScope.findByValue(iprot.readI32());
-                    struct.scopes.add(_elem322);
+                    _elem321 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                    struct.scopes.add(_elem321);
                   }
                   iprot.readSetEnd();
                 }
@@ -48677,11 +53536,11 @@
           {
             org.apache.thrift.protocol.TSet _set325 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
             struct.scopes = new HashSet<IteratorScope>(2*_set325.size);
-            for (int _i326 = 0; _i326 < _set325.size; ++_i326)
+            IteratorScope _elem326;
+            for (int _i327 = 0; _i327 < _set325.size; ++_i327)
             {
-              IteratorScope _elem327;
-              _elem327 = IteratorScope.findByValue(iprot.readI32());
-              struct.scopes.add(_elem327);
+              _elem326 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+              struct.scopes.add(_elem326);
             }
           }
           struct.setScopesIsSet(true);
@@ -49004,7 +53863,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -49355,7 +54231,7 @@
       String property)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.property = property;
     }
@@ -49366,7 +54242,6 @@
     public removeTableProperty_args(removeTableProperty_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -49393,16 +54268,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public removeTableProperty_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public removeTableProperty_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -49575,7 +54450,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_property = true && (isSetProperty());
+      list.add(present_property);
+      if (present_property)
+        list.add(property);
+
+      return list.hashCode();
     }
 
     @Override
@@ -50129,7 +55021,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -50480,7 +55389,7 @@
       String newTableName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.oldTableName = oldTableName;
       this.newTableName = newTableName;
     }
@@ -50491,7 +55400,6 @@
     public renameTable_args(renameTable_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetOldTableName()) {
         this.oldTableName = other.oldTableName;
@@ -50518,16 +55426,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public renameTable_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public renameTable_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -50700,7 +55608,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_oldTableName = true && (isSetOldTableName());
+      list.add(present_oldTableName);
+      if (present_oldTableName)
+        list.add(oldTableName);
+
+      boolean present_newTableName = true && (isSetNewTableName());
+      list.add(present_newTableName);
+      if (present_newTableName)
+        list.add(newTableName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -51313,7 +56238,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      boolean present_ouch4 = true && (isSetOuch4());
+      list.add(present_ouch4);
+      if (present_ouch4)
+        list.add(ouch4);
+
+      return list.hashCode();
     }
 
     @Override
@@ -51710,7 +56657,7 @@
       Map<String,Set<String>> groups)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.groups = groups;
     }
@@ -51721,7 +56668,6 @@
     public setLocalityGroups_args(setLocalityGroups_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -51760,16 +56706,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public setLocalityGroups_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public setLocalityGroups_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -51953,7 +56899,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_groups = true && (isSetGroups());
+      list.add(present_groups);
+      if (present_groups)
+        list.add(groups);
+
+      return list.hashCode();
     }
 
     @Override
@@ -52101,23 +57064,23 @@
                 {
                   org.apache.thrift.protocol.TMap _map328 = iprot.readMapBegin();
                   struct.groups = new HashMap<String,Set<String>>(2*_map328.size);
-                  for (int _i329 = 0; _i329 < _map328.size; ++_i329)
+                  String _key329;
+                  Set<String> _val330;
+                  for (int _i331 = 0; _i331 < _map328.size; ++_i331)
                   {
-                    String _key330;
-                    Set<String> _val331;
-                    _key330 = iprot.readString();
+                    _key329 = iprot.readString();
                     {
                       org.apache.thrift.protocol.TSet _set332 = iprot.readSetBegin();
-                      _val331 = new HashSet<String>(2*_set332.size);
-                      for (int _i333 = 0; _i333 < _set332.size; ++_i333)
+                      _val330 = new HashSet<String>(2*_set332.size);
+                      String _elem333;
+                      for (int _i334 = 0; _i334 < _set332.size; ++_i334)
                       {
-                        String _elem334;
-                        _elem334 = iprot.readString();
-                        _val331.add(_elem334);
+                        _elem333 = iprot.readString();
+                        _val330.add(_elem333);
                       }
                       iprot.readSetEnd();
                     }
-                    struct.groups.put(_key330, _val331);
+                    struct.groups.put(_key329, _val330);
                   }
                   iprot.readMapEnd();
                 }
@@ -52239,22 +57202,22 @@
           {
             org.apache.thrift.protocol.TMap _map339 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, iprot.readI32());
             struct.groups = new HashMap<String,Set<String>>(2*_map339.size);
-            for (int _i340 = 0; _i340 < _map339.size; ++_i340)
+            String _key340;
+            Set<String> _val341;
+            for (int _i342 = 0; _i342 < _map339.size; ++_i342)
             {
-              String _key341;
-              Set<String> _val342;
-              _key341 = iprot.readString();
+              _key340 = iprot.readString();
               {
                 org.apache.thrift.protocol.TSet _set343 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
-                _val342 = new HashSet<String>(2*_set343.size);
-                for (int _i344 = 0; _i344 < _set343.size; ++_i344)
+                _val341 = new HashSet<String>(2*_set343.size);
+                String _elem344;
+                for (int _i345 = 0; _i345 < _set343.size; ++_i345)
                 {
-                  String _elem345;
-                  _elem345 = iprot.readString();
-                  _val342.add(_elem345);
+                  _elem344 = iprot.readString();
+                  _val341.add(_elem344);
                 }
               }
-              struct.groups.put(_key341, _val342);
+              struct.groups.put(_key340, _val341);
             }
           }
           struct.setGroupsIsSet(true);
@@ -52577,7 +57540,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -52936,7 +57916,7 @@
       String value)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.property = property;
       this.value = value;
@@ -52948,7 +57928,6 @@
     public setTableProperty_args(setTableProperty_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -52979,16 +57958,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public setTableProperty_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public setTableProperty_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -53207,7 +58186,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_property = true && (isSetProperty());
+      list.add(present_property);
+      if (present_property)
+        list.add(property);
+
+      boolean present_value = true && (isSetValue());
+      list.add(present_value);
+      if (present_value)
+        list.add(value);
+
+      return list.hashCode();
     }
 
     @Override
@@ -53802,7 +58803,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -54163,7 +59181,7 @@
       int maxSplits)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.range = range;
       this.maxSplits = maxSplits;
@@ -54177,7 +59195,6 @@
       __isset_bitfield = other.__isset_bitfield;
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -54207,16 +59224,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public splitRangeByTablets_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public splitRangeByTablets_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -54355,7 +59372,7 @@
         return getRange();
 
       case MAX_SPLITS:
-        return Integer.valueOf(getMaxSplits());
+        return getMaxSplits();
 
       }
       throw new IllegalStateException();
@@ -54434,7 +59451,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_range = true && (isSetRange());
+      list.add(present_range);
+      if (present_range)
+        list.add(range);
+
+      boolean present_maxSplits = true;
+      list.add(present_maxSplits);
+      if (present_maxSplits)
+        list.add(maxSplits);
+
+      return list.hashCode();
     }
 
     @Override
@@ -55109,7 +60148,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -55259,12 +60320,12 @@
                 {
                   org.apache.thrift.protocol.TSet _set346 = iprot.readSetBegin();
                   struct.success = new HashSet<Range>(2*_set346.size);
-                  for (int _i347 = 0; _i347 < _set346.size; ++_i347)
+                  Range _elem347;
+                  for (int _i348 = 0; _i348 < _set346.size; ++_i348)
                   {
-                    Range _elem348;
-                    _elem348 = new Range();
-                    _elem348.read(iprot);
-                    struct.success.add(_elem348);
+                    _elem347 = new Range();
+                    _elem347.read(iprot);
+                    struct.success.add(_elem347);
                   }
                   iprot.readSetEnd();
                 }
@@ -55401,12 +60462,12 @@
           {
             org.apache.thrift.protocol.TSet _set351 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
             struct.success = new HashSet<Range>(2*_set351.size);
-            for (int _i352 = 0; _i352 < _set351.size; ++_i352)
+            Range _elem352;
+            for (int _i353 = 0; _i353 < _set351.size; ++_i353)
             {
-              Range _elem353;
-              _elem353 = new Range();
-              _elem353.read(iprot);
-              struct.success.add(_elem353);
+              _elem352 = new Range();
+              _elem352.read(iprot);
+              struct.success.add(_elem352);
             }
           }
           struct.setSuccessIsSet(true);
@@ -55527,7 +60588,7 @@
       String tableName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
     }
 
@@ -55537,7 +60598,6 @@
     public tableExists_args(tableExists_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -55560,16 +60620,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public tableExists_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public tableExists_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -55696,7 +60756,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -56047,7 +61119,7 @@
     public Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
-        return Boolean.valueOf(isSuccess());
+        return isSuccess();
 
       }
       throw new IllegalStateException();
@@ -56093,7 +61165,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      return list.hashCode();
     }
 
     @Override
@@ -56338,7 +61417,7 @@
       ByteBuffer login)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     /**
@@ -56347,7 +61426,6 @@
     public tableIdMap_args(tableIdMap_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
     }
 
@@ -56366,16 +61444,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public tableIdMap_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public tableIdMap_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -56456,7 +61534,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      return list.hashCode();
     }
 
     @Override
@@ -56824,7 +61909,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      return list.hashCode();
     }
 
     @Override
@@ -56920,13 +62012,13 @@
                 {
                   org.apache.thrift.protocol.TMap _map354 = iprot.readMapBegin();
                   struct.success = new HashMap<String,String>(2*_map354.size);
-                  for (int _i355 = 0; _i355 < _map354.size; ++_i355)
+                  String _key355;
+                  String _val356;
+                  for (int _i357 = 0; _i357 < _map354.size; ++_i357)
                   {
-                    String _key356;
-                    String _val357;
-                    _key356 = iprot.readString();
-                    _val357 = iprot.readString();
-                    struct.success.put(_key356, _val357);
+                    _key355 = iprot.readString();
+                    _val356 = iprot.readString();
+                    struct.success.put(_key355, _val356);
                   }
                   iprot.readMapEnd();
                 }
@@ -57005,13 +62097,13 @@
           {
             org.apache.thrift.protocol.TMap _map360 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.success = new HashMap<String,String>(2*_map360.size);
-            for (int _i361 = 0; _i361 < _map360.size; ++_i361)
+            String _key361;
+            String _val362;
+            for (int _i363 = 0; _i363 < _map360.size; ++_i363)
             {
-              String _key362;
-              String _val363;
-              _key362 = iprot.readString();
-              _val363 = iprot.readString();
-              struct.success.put(_key362, _val363);
+              _key361 = iprot.readString();
+              _val362 = iprot.readString();
+              struct.success.put(_key361, _val362);
             }
           }
           struct.setSuccessIsSet(true);
@@ -57133,7 +62225,7 @@
       String asTypeName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.className = className;
       this.asTypeName = asTypeName;
@@ -57145,7 +62237,6 @@
     public testTableClassLoad_args(testTableClassLoad_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -57176,16 +62267,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public testTableClassLoad_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public testTableClassLoad_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -57404,7 +62495,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_className = true && (isSetClassName());
+      list.add(present_className);
+      if (present_className)
+        list.add(className);
+
+      boolean present_asTypeName = true && (isSetAsTypeName());
+      list.add(present_asTypeName);
+      if (present_asTypeName)
+        list.add(asTypeName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -57972,7 +63085,7 @@
     public Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
-        return Boolean.valueOf(isSuccess());
+        return isSuccess();
 
       case OUCH1:
         return getOuch1();
@@ -58060,7 +63173,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -58442,7 +63577,7 @@
       String tserver)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tserver = tserver;
     }
 
@@ -58452,7 +63587,6 @@
     public pingTabletServer_args(pingTabletServer_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTserver()) {
         this.tserver = other.tserver;
@@ -58475,16 +63609,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public pingTabletServer_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public pingTabletServer_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -58611,7 +63745,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tserver = true && (isSetTserver());
+      list.add(present_tserver);
+      if (present_tserver)
+        list.add(tserver);
+
+      return list.hashCode();
     }
 
     @Override
@@ -59065,7 +64211,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -59365,7 +64523,7 @@
       String tserver)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tserver = tserver;
     }
 
@@ -59375,7 +64533,6 @@
     public getActiveScans_args(getActiveScans_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTserver()) {
         this.tserver = other.tserver;
@@ -59398,16 +64555,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getActiveScans_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getActiveScans_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -59534,7 +64691,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tserver = true && (isSetTserver());
+      list.add(present_tserver);
+      if (present_tserver)
+        list.add(tserver);
+
+      return list.hashCode();
     }
 
     @Override
@@ -60067,7 +65236,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -60199,12 +65385,12 @@
                 {
                   org.apache.thrift.protocol.TList _list364 = iprot.readListBegin();
                   struct.success = new ArrayList<ActiveScan>(_list364.size);
-                  for (int _i365 = 0; _i365 < _list364.size; ++_i365)
+                  ActiveScan _elem365;
+                  for (int _i366 = 0; _i366 < _list364.size; ++_i366)
                   {
-                    ActiveScan _elem366;
-                    _elem366 = new ActiveScan();
-                    _elem366.read(iprot);
-                    struct.success.add(_elem366);
+                    _elem365 = new ActiveScan();
+                    _elem365.read(iprot);
+                    struct.success.add(_elem365);
                   }
                   iprot.readListEnd();
                 }
@@ -60321,12 +65507,12 @@
           {
             org.apache.thrift.protocol.TList _list369 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
             struct.success = new ArrayList<ActiveScan>(_list369.size);
-            for (int _i370 = 0; _i370 < _list369.size; ++_i370)
+            ActiveScan _elem370;
+            for (int _i371 = 0; _i371 < _list369.size; ++_i371)
             {
-              ActiveScan _elem371;
-              _elem371 = new ActiveScan();
-              _elem371.read(iprot);
-              struct.success.add(_elem371);
+              _elem370 = new ActiveScan();
+              _elem370.read(iprot);
+              struct.success.add(_elem370);
             }
           }
           struct.setSuccessIsSet(true);
@@ -60442,7 +65628,7 @@
       String tserver)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tserver = tserver;
     }
 
@@ -60452,7 +65638,6 @@
     public getActiveCompactions_args(getActiveCompactions_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTserver()) {
         this.tserver = other.tserver;
@@ -60475,16 +65660,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getActiveCompactions_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getActiveCompactions_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -60611,7 +65796,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tserver = true && (isSetTserver());
+      list.add(present_tserver);
+      if (present_tserver)
+        list.add(tserver);
+
+      return list.hashCode();
     }
 
     @Override
@@ -61144,7 +66341,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -61276,12 +66490,12 @@
                 {
                   org.apache.thrift.protocol.TList _list372 = iprot.readListBegin();
                   struct.success = new ArrayList<ActiveCompaction>(_list372.size);
-                  for (int _i373 = 0; _i373 < _list372.size; ++_i373)
+                  ActiveCompaction _elem373;
+                  for (int _i374 = 0; _i374 < _list372.size; ++_i374)
                   {
-                    ActiveCompaction _elem374;
-                    _elem374 = new ActiveCompaction();
-                    _elem374.read(iprot);
-                    struct.success.add(_elem374);
+                    _elem373 = new ActiveCompaction();
+                    _elem373.read(iprot);
+                    struct.success.add(_elem373);
                   }
                   iprot.readListEnd();
                 }
@@ -61398,12 +66612,12 @@
           {
             org.apache.thrift.protocol.TList _list377 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
             struct.success = new ArrayList<ActiveCompaction>(_list377.size);
-            for (int _i378 = 0; _i378 < _list377.size; ++_i378)
+            ActiveCompaction _elem378;
+            for (int _i379 = 0; _i379 < _list377.size; ++_i379)
             {
-              ActiveCompaction _elem379;
-              _elem379 = new ActiveCompaction();
-              _elem379.read(iprot);
-              struct.success.add(_elem379);
+              _elem378 = new ActiveCompaction();
+              _elem378.read(iprot);
+              struct.success.add(_elem378);
             }
           }
           struct.setSuccessIsSet(true);
@@ -61511,7 +66725,7 @@
       ByteBuffer login)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     /**
@@ -61520,7 +66734,6 @@
     public getSiteConfiguration_args(getSiteConfiguration_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
     }
 
@@ -61539,16 +66752,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getSiteConfiguration_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getSiteConfiguration_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -61629,7 +66842,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      return list.hashCode();
     }
 
     @Override
@@ -62115,7 +67335,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -62247,13 +67484,13 @@
                 {
                   org.apache.thrift.protocol.TMap _map380 = iprot.readMapBegin();
                   struct.success = new HashMap<String,String>(2*_map380.size);
-                  for (int _i381 = 0; _i381 < _map380.size; ++_i381)
+                  String _key381;
+                  String _val382;
+                  for (int _i383 = 0; _i383 < _map380.size; ++_i383)
                   {
-                    String _key382;
-                    String _val383;
-                    _key382 = iprot.readString();
-                    _val383 = iprot.readString();
-                    struct.success.put(_key382, _val383);
+                    _key381 = iprot.readString();
+                    _val382 = iprot.readString();
+                    struct.success.put(_key381, _val382);
                   }
                   iprot.readMapEnd();
                 }
@@ -62372,13 +67609,13 @@
           {
             org.apache.thrift.protocol.TMap _map386 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.success = new HashMap<String,String>(2*_map386.size);
-            for (int _i387 = 0; _i387 < _map386.size; ++_i387)
+            String _key387;
+            String _val388;
+            for (int _i389 = 0; _i389 < _map386.size; ++_i389)
             {
-              String _key388;
-              String _val389;
-              _key388 = iprot.readString();
-              _val389 = iprot.readString();
-              struct.success.put(_key388, _val389);
+              _key387 = iprot.readString();
+              _val388 = iprot.readString();
+              struct.success.put(_key387, _val388);
             }
           }
           struct.setSuccessIsSet(true);
@@ -62486,7 +67723,7 @@
       ByteBuffer login)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     /**
@@ -62495,7 +67732,6 @@
     public getSystemConfiguration_args(getSystemConfiguration_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
     }
 
@@ -62514,16 +67750,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getSystemConfiguration_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getSystemConfiguration_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -62604,7 +67840,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      return list.hashCode();
     }
 
     @Override
@@ -63090,7 +68333,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -63222,13 +68482,13 @@
                 {
                   org.apache.thrift.protocol.TMap _map390 = iprot.readMapBegin();
                   struct.success = new HashMap<String,String>(2*_map390.size);
-                  for (int _i391 = 0; _i391 < _map390.size; ++_i391)
+                  String _key391;
+                  String _val392;
+                  for (int _i393 = 0; _i393 < _map390.size; ++_i393)
                   {
-                    String _key392;
-                    String _val393;
-                    _key392 = iprot.readString();
-                    _val393 = iprot.readString();
-                    struct.success.put(_key392, _val393);
+                    _key391 = iprot.readString();
+                    _val392 = iprot.readString();
+                    struct.success.put(_key391, _val392);
                   }
                   iprot.readMapEnd();
                 }
@@ -63347,13 +68607,13 @@
           {
             org.apache.thrift.protocol.TMap _map396 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.success = new HashMap<String,String>(2*_map396.size);
-            for (int _i397 = 0; _i397 < _map396.size; ++_i397)
+            String _key397;
+            String _val398;
+            for (int _i399 = 0; _i399 < _map396.size; ++_i399)
             {
-              String _key398;
-              String _val399;
-              _key398 = iprot.readString();
-              _val399 = iprot.readString();
-              struct.success.put(_key398, _val399);
+              _key397 = iprot.readString();
+              _val398 = iprot.readString();
+              struct.success.put(_key397, _val398);
             }
           }
           struct.setSuccessIsSet(true);
@@ -63461,7 +68721,7 @@
       ByteBuffer login)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     /**
@@ -63470,7 +68730,6 @@
     public getTabletServers_args(getTabletServers_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
     }
 
@@ -63489,16 +68748,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getTabletServers_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getTabletServers_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -63579,7 +68838,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      return list.hashCode();
     }
 
     @Override
@@ -63950,7 +69216,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      return list.hashCode();
     }
 
     @Override
@@ -64046,11 +69319,11 @@
                 {
                   org.apache.thrift.protocol.TList _list400 = iprot.readListBegin();
                   struct.success = new ArrayList<String>(_list400.size);
-                  for (int _i401 = 0; _i401 < _list400.size; ++_i401)
+                  String _elem401;
+                  for (int _i402 = 0; _i402 < _list400.size; ++_i402)
                   {
-                    String _elem402;
-                    _elem402 = iprot.readString();
-                    struct.success.add(_elem402);
+                    _elem401 = iprot.readString();
+                    struct.success.add(_elem401);
                   }
                   iprot.readListEnd();
                 }
@@ -64127,11 +69400,11 @@
           {
             org.apache.thrift.protocol.TList _list405 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.success = new ArrayList<String>(_list405.size);
-            for (int _i406 = 0; _i406 < _list405.size; ++_i406)
+            String _elem406;
+            for (int _i407 = 0; _i407 < _list405.size; ++_i407)
             {
-              String _elem407;
-              _elem407 = iprot.readString();
-              struct.success.add(_elem407);
+              _elem406 = iprot.readString();
+              struct.success.add(_elem406);
             }
           }
           struct.setSuccessIsSet(true);
@@ -64237,7 +69510,7 @@
       String property)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.property = property;
     }
 
@@ -64247,7 +69520,6 @@
     public removeProperty_args(removeProperty_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetProperty()) {
         this.property = other.property;
@@ -64270,16 +69542,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public removeProperty_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public removeProperty_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -64406,7 +69678,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_property = true && (isSetProperty());
+      list.add(present_property);
+      if (present_property)
+        list.add(property);
+
+      return list.hashCode();
     }
 
     @Override
@@ -64860,7 +70144,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -65168,7 +70464,7 @@
       String value)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.property = property;
       this.value = value;
     }
@@ -65179,7 +70475,6 @@
     public setProperty_args(setProperty_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetProperty()) {
         this.property = other.property;
@@ -65206,16 +70501,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public setProperty_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public setProperty_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -65388,7 +70683,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_property = true && (isSetProperty());
+      list.add(present_property);
+      if (present_property)
+        list.add(property);
+
+      boolean present_value = true && (isSetValue());
+      list.add(present_value);
+      if (present_value)
+        list.add(value);
+
+      return list.hashCode();
     }
 
     @Override
@@ -65883,7 +71195,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -66191,7 +71515,7 @@
       String asTypeName)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.className = className;
       this.asTypeName = asTypeName;
     }
@@ -66202,7 +71526,6 @@
     public testClassLoad_args(testClassLoad_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetClassName()) {
         this.className = other.className;
@@ -66229,16 +71552,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public testClassLoad_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public testClassLoad_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -66411,7 +71734,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_className = true && (isSetClassName());
+      list.add(present_className);
+      if (present_className)
+        list.add(className);
+
+      boolean present_asTypeName = true && (isSetAsTypeName());
+      list.add(present_asTypeName);
+      if (present_asTypeName)
+        list.add(asTypeName);
+
+      return list.hashCode();
     }
 
     @Override
@@ -66893,7 +72233,7 @@
     public Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
-        return Boolean.valueOf(isSuccess());
+        return isSuccess();
 
       case OUCH1:
         return getOuch1();
@@ -66967,7 +72307,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -67316,7 +72673,7 @@
       Map<String,String> properties)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
       this.properties = properties;
     }
@@ -67327,7 +72684,6 @@
     public authenticateUser_args(authenticateUser_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
@@ -67355,16 +72711,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public authenticateUser_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public authenticateUser_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -67548,7 +72904,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_properties = true && (isSetProperties());
+      list.add(present_properties);
+      if (present_properties)
+        list.add(properties);
+
+      return list.hashCode();
     }
 
     @Override
@@ -67696,13 +73069,13 @@
                 {
                   org.apache.thrift.protocol.TMap _map408 = iprot.readMapBegin();
                   struct.properties = new HashMap<String,String>(2*_map408.size);
-                  for (int _i409 = 0; _i409 < _map408.size; ++_i409)
+                  String _key409;
+                  String _val410;
+                  for (int _i411 = 0; _i411 < _map408.size; ++_i411)
                   {
-                    String _key410;
-                    String _val411;
-                    _key410 = iprot.readString();
-                    _val411 = iprot.readString();
-                    struct.properties.put(_key410, _val411);
+                    _key409 = iprot.readString();
+                    _val410 = iprot.readString();
+                    struct.properties.put(_key409, _val410);
                   }
                   iprot.readMapEnd();
                 }
@@ -67811,13 +73184,13 @@
           {
             org.apache.thrift.protocol.TMap _map414 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.properties = new HashMap<String,String>(2*_map414.size);
-            for (int _i415 = 0; _i415 < _map414.size; ++_i415)
+            String _key415;
+            String _val416;
+            for (int _i417 = 0; _i417 < _map414.size; ++_i417)
             {
-              String _key416;
-              String _val417;
-              _key416 = iprot.readString();
-              _val417 = iprot.readString();
-              struct.properties.put(_key416, _val417);
+              _key415 = iprot.readString();
+              _val416 = iprot.readString();
+              struct.properties.put(_key415, _val416);
             }
           }
           struct.setPropertiesIsSet(true);
@@ -68068,7 +73441,7 @@
     public Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
-        return Boolean.valueOf(isSuccess());
+        return isSuccess();
 
       case OUCH1:
         return getOuch1();
@@ -68142,7 +73515,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -68490,7 +73880,7 @@
       Set<ByteBuffer> authorizations)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
       this.authorizations = authorizations;
     }
@@ -68501,7 +73891,6 @@
     public changeUserAuthorizations_args(changeUserAuthorizations_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
@@ -68529,16 +73918,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public changeUserAuthorizations_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public changeUserAuthorizations_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -68726,7 +74115,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_authorizations = true && (isSetAuthorizations());
+      list.add(present_authorizations);
+      if (present_authorizations)
+        list.add(authorizations);
+
+      return list.hashCode();
     }
 
     @Override
@@ -68807,7 +74213,7 @@
       if (this.authorizations == null) {
         sb.append("null");
       } else {
-        sb.append(this.authorizations);
+        org.apache.thrift.TBaseHelper.toString(this.authorizations, sb);
       }
       first = false;
       sb.append(")");
@@ -68874,11 +74280,11 @@
                 {
                   org.apache.thrift.protocol.TSet _set418 = iprot.readSetBegin();
                   struct.authorizations = new HashSet<ByteBuffer>(2*_set418.size);
-                  for (int _i419 = 0; _i419 < _set418.size; ++_i419)
+                  ByteBuffer _elem419;
+                  for (int _i420 = 0; _i420 < _set418.size; ++_i420)
                   {
-                    ByteBuffer _elem420;
-                    _elem420 = iprot.readBinary();
-                    struct.authorizations.add(_elem420);
+                    _elem419 = iprot.readBinary();
+                    struct.authorizations.add(_elem419);
                   }
                   iprot.readSetEnd();
                 }
@@ -68985,11 +74391,11 @@
           {
             org.apache.thrift.protocol.TSet _set423 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.authorizations = new HashSet<ByteBuffer>(2*_set423.size);
-            for (int _i424 = 0; _i424 < _set423.size; ++_i424)
+            ByteBuffer _elem424;
+            for (int _i425 = 0; _i425 < _set423.size; ++_i425)
             {
-              ByteBuffer _elem425;
-              _elem425 = iprot.readBinary();
-              struct.authorizations.add(_elem425);
+              _elem424 = iprot.readBinary();
+              struct.authorizations.add(_elem424);
             }
           }
           struct.setAuthorizationsIsSet(true);
@@ -69253,7 +74659,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -69561,9 +74979,9 @@
       ByteBuffer password)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
-      this.password = password;
+      this.password = org.apache.thrift.TBaseHelper.copyBinary(password);
     }
 
     /**
@@ -69572,14 +74990,12 @@
     public changeLocalUserPassword_args(changeLocalUserPassword_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
       }
       if (other.isSetPassword()) {
         this.password = org.apache.thrift.TBaseHelper.copyBinary(other.password);
-;
       }
     }
 
@@ -69600,16 +75016,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public changeLocalUserPassword_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public changeLocalUserPassword_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -69658,16 +75074,16 @@
     }
 
     public ByteBuffer bufferForPassword() {
-      return password;
+      return org.apache.thrift.TBaseHelper.copyBinary(password);
     }
 
     public changeLocalUserPassword_args setPassword(byte[] password) {
-      setPassword(password == null ? (ByteBuffer)null : ByteBuffer.wrap(password));
+      this.password = password == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(password, password.length));
       return this;
     }
 
     public changeLocalUserPassword_args setPassword(ByteBuffer password) {
-      this.password = password;
+      this.password = org.apache.thrift.TBaseHelper.copyBinary(password);
       return this;
     }
 
@@ -69792,7 +75208,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_password = true && (isSetPassword());
+      list.add(present_password);
+      if (present_password)
+        list.add(password);
+
+      return list.hashCode();
     }
 
     @Override
@@ -70287,7 +75720,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -70595,9 +76040,9 @@
       ByteBuffer password)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
-      this.password = password;
+      this.password = org.apache.thrift.TBaseHelper.copyBinary(password);
     }
 
     /**
@@ -70606,14 +76051,12 @@
     public createLocalUser_args(createLocalUser_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
       }
       if (other.isSetPassword()) {
         this.password = org.apache.thrift.TBaseHelper.copyBinary(other.password);
-;
       }
     }
 
@@ -70634,16 +76077,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createLocalUser_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public createLocalUser_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -70692,16 +76135,16 @@
     }
 
     public ByteBuffer bufferForPassword() {
-      return password;
+      return org.apache.thrift.TBaseHelper.copyBinary(password);
     }
 
     public createLocalUser_args setPassword(byte[] password) {
-      setPassword(password == null ? (ByteBuffer)null : ByteBuffer.wrap(password));
+      this.password = password == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(password, password.length));
       return this;
     }
 
     public createLocalUser_args setPassword(ByteBuffer password) {
-      this.password = password;
+      this.password = org.apache.thrift.TBaseHelper.copyBinary(password);
       return this;
     }
 
@@ -70826,7 +76269,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_password = true && (isSetPassword());
+      list.add(present_password);
+      if (present_password)
+        list.add(password);
+
+      return list.hashCode();
     }
 
     @Override
@@ -71321,7 +76781,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -71621,7 +77093,7 @@
       String user)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
     }
 
@@ -71631,7 +77103,6 @@
     public dropLocalUser_args(dropLocalUser_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
@@ -71654,16 +77125,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public dropLocalUser_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public dropLocalUser_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -71790,7 +77261,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      return list.hashCode();
     }
 
     @Override
@@ -72244,7 +77727,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -72544,7 +78039,7 @@
       String user)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
     }
 
@@ -72554,7 +78049,6 @@
     public getUserAuthorizations_args(getUserAuthorizations_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
@@ -72577,16 +78071,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getUserAuthorizations_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public getUserAuthorizations_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -72713,7 +78207,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      return list.hashCode();
     }
 
     @Override
@@ -73243,7 +78749,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -73308,7 +78831,7 @@
       if (this.success == null) {
         sb.append("null");
       } else {
-        sb.append(this.success);
+        org.apache.thrift.TBaseHelper.toString(this.success, sb);
       }
       first = false;
       if (!first) sb.append(", ");
@@ -73375,11 +78898,11 @@
                 {
                   org.apache.thrift.protocol.TList _list426 = iprot.readListBegin();
                   struct.success = new ArrayList<ByteBuffer>(_list426.size);
-                  for (int _i427 = 0; _i427 < _list426.size; ++_i427)
+                  ByteBuffer _elem427;
+                  for (int _i428 = 0; _i428 < _list426.size; ++_i428)
                   {
-                    ByteBuffer _elem428;
-                    _elem428 = iprot.readBinary();
-                    struct.success.add(_elem428);
+                    _elem427 = iprot.readBinary();
+                    struct.success.add(_elem427);
                   }
                   iprot.readListEnd();
                 }
@@ -73496,11 +79019,11 @@
           {
             org.apache.thrift.protocol.TList _list431 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.success = new ArrayList<ByteBuffer>(_list431.size);
-            for (int _i432 = 0; _i432 < _list431.size; ++_i432)
+            ByteBuffer _elem432;
+            for (int _i433 = 0; _i433 < _list431.size; ++_i433)
             {
-              ByteBuffer _elem433;
-              _elem433 = iprot.readBinary();
-              struct.success.add(_elem433);
+              _elem432 = iprot.readBinary();
+              struct.success.add(_elem432);
             }
           }
           struct.setSuccessIsSet(true);
@@ -73632,7 +79155,7 @@
       SystemPermission perm)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
       this.perm = perm;
     }
@@ -73643,7 +79166,6 @@
     public grantSystemPermission_args(grantSystemPermission_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
@@ -73670,16 +79192,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public grantSystemPermission_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public grantSystemPermission_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -73860,7 +79382,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_perm = true && (isSetPerm());
+      list.add(present_perm);
+      if (present_perm)
+        list.add(perm.getValue());
+
+      return list.hashCode();
     }
 
     @Override
@@ -74005,7 +79544,7 @@
               break;
             case 3: // PERM
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-                struct.perm = SystemPermission.findByValue(iprot.readI32());
+                struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
                 struct.setPermIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -74093,7 +79632,7 @@
           struct.setUserIsSet(true);
         }
         if (incoming.get(2)) {
-          struct.perm = SystemPermission.findByValue(iprot.readI32());
+          struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
           struct.setPermIsSet(true);
         }
       }
@@ -74355,7 +79894,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -74679,7 +80230,7 @@
       TablePermission perm)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
       this.table = table;
       this.perm = perm;
@@ -74691,7 +80242,6 @@
     public grantTablePermission_args(grantTablePermission_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
@@ -74722,16 +80272,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public grantTablePermission_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public grantTablePermission_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -74958,7 +80508,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_table = true && (isSetTable());
+      list.add(present_table);
+      if (present_table)
+        list.add(table);
+
+      boolean present_perm = true && (isSetPerm());
+      list.add(present_perm);
+      if (present_perm)
+        list.add(perm.getValue());
+
+      return list.hashCode();
     }
 
     @Override
@@ -75129,7 +80701,7 @@
               break;
             case 4: // PERM
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-                struct.perm = TablePermission.findByValue(iprot.readI32());
+                struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
                 struct.setPermIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -75232,7 +80804,7 @@
           struct.setTableIsSet(true);
         }
         if (incoming.get(3)) {
-          struct.perm = TablePermission.findByValue(iprot.readI32());
+          struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
           struct.setPermIsSet(true);
         }
       }
@@ -75553,7 +81125,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -75912,7 +81501,7 @@
       SystemPermission perm)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
       this.perm = perm;
     }
@@ -75923,7 +81512,6 @@
     public hasSystemPermission_args(hasSystemPermission_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
@@ -75950,16 +81538,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public hasSystemPermission_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public hasSystemPermission_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -76140,7 +81728,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_perm = true && (isSetPerm());
+      list.add(present_perm);
+      if (present_perm)
+        list.add(perm.getValue());
+
+      return list.hashCode();
     }
 
     @Override
@@ -76285,7 +81890,7 @@
               break;
             case 3: // PERM
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-                struct.perm = SystemPermission.findByValue(iprot.readI32());
+                struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
                 struct.setPermIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -76373,7 +81978,7 @@
           struct.setUserIsSet(true);
         }
         if (incoming.get(2)) {
-          struct.perm = SystemPermission.findByValue(iprot.readI32());
+          struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
           struct.setPermIsSet(true);
         }
       }
@@ -76622,7 +82227,7 @@
     public Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
-        return Boolean.valueOf(isSuccess());
+        return isSuccess();
 
       case OUCH1:
         return getOuch1();
@@ -76696,7 +82301,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -77059,7 +82681,7 @@
       TablePermission perm)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
       this.table = table;
       this.perm = perm;
@@ -77071,7 +82693,6 @@
     public hasTablePermission_args(hasTablePermission_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
@@ -77102,16 +82723,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public hasTablePermission_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public hasTablePermission_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -77338,7 +82959,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_table = true && (isSetTable());
+      list.add(present_table);
+      if (present_table)
+        list.add(table);
+
+      boolean present_perm = true && (isSetPerm());
+      list.add(present_perm);
+      if (present_perm)
+        list.add(perm.getValue());
+
+      return list.hashCode();
     }
 
     @Override
@@ -77509,7 +83152,7 @@
               break;
             case 4: // PERM
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-                struct.perm = TablePermission.findByValue(iprot.readI32());
+                struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
                 struct.setPermIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -77612,7 +83255,7 @@
           struct.setTableIsSet(true);
         }
         if (incoming.get(3)) {
-          struct.perm = TablePermission.findByValue(iprot.readI32());
+          struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
           struct.setPermIsSet(true);
         }
       }
@@ -77906,7 +83549,7 @@
     public Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
-        return Boolean.valueOf(isSuccess());
+        return isSuccess();
 
       case OUCH1:
         return getOuch1();
@@ -77994,7 +83637,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -78368,7 +84033,7 @@
       ByteBuffer login)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     /**
@@ -78377,7 +84042,6 @@
     public listLocalUsers_args(listLocalUsers_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
     }
 
@@ -78396,16 +84060,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public listLocalUsers_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public listLocalUsers_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -78486,7 +84150,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      return list.hashCode();
     }
 
     @Override
@@ -79034,7 +84705,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -79184,11 +84877,11 @@
                 {
                   org.apache.thrift.protocol.TSet _set434 = iprot.readSetBegin();
                   struct.success = new HashSet<String>(2*_set434.size);
-                  for (int _i435 = 0; _i435 < _set434.size; ++_i435)
+                  String _elem435;
+                  for (int _i436 = 0; _i436 < _set434.size; ++_i436)
                   {
-                    String _elem436;
-                    _elem436 = iprot.readString();
-                    struct.success.add(_elem436);
+                    _elem435 = iprot.readString();
+                    struct.success.add(_elem435);
                   }
                   iprot.readSetEnd();
                 }
@@ -79325,11 +85018,11 @@
           {
             org.apache.thrift.protocol.TSet _set439 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
             struct.success = new HashSet<String>(2*_set439.size);
-            for (int _i440 = 0; _i440 < _set439.size; ++_i440)
+            String _elem440;
+            for (int _i441 = 0; _i441 < _set439.size; ++_i441)
             {
-              String _elem441;
-              _elem441 = iprot.readString();
-              struct.success.add(_elem441);
+              _elem440 = iprot.readString();
+              struct.success.add(_elem440);
             }
           }
           struct.setSuccessIsSet(true);
@@ -79466,7 +85159,7 @@
       SystemPermission perm)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
       this.perm = perm;
     }
@@ -79477,7 +85170,6 @@
     public revokeSystemPermission_args(revokeSystemPermission_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
@@ -79504,16 +85196,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public revokeSystemPermission_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public revokeSystemPermission_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -79694,7 +85386,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_perm = true && (isSetPerm());
+      list.add(present_perm);
+      if (present_perm)
+        list.add(perm.getValue());
+
+      return list.hashCode();
     }
 
     @Override
@@ -79839,7 +85548,7 @@
               break;
             case 3: // PERM
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-                struct.perm = SystemPermission.findByValue(iprot.readI32());
+                struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
                 struct.setPermIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -79927,7 +85636,7 @@
           struct.setUserIsSet(true);
         }
         if (incoming.get(2)) {
-          struct.perm = SystemPermission.findByValue(iprot.readI32());
+          struct.perm = org.apache.accumulo.proxy.thrift.SystemPermission.findByValue(iprot.readI32());
           struct.setPermIsSet(true);
         }
       }
@@ -80189,7 +85898,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -80513,7 +86234,7 @@
       TablePermission perm)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.user = user;
       this.table = table;
       this.perm = perm;
@@ -80525,7 +86246,6 @@
     public revokeTablePermission_args(revokeTablePermission_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetUser()) {
         this.user = other.user;
@@ -80556,16 +86276,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public revokeTablePermission_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public revokeTablePermission_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -80792,7 +86512,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_table = true && (isSetTable());
+      list.add(present_table);
+      if (present_table)
+        list.add(table);
+
+      boolean present_perm = true && (isSetPerm());
+      list.add(present_perm);
+      if (present_perm)
+        list.add(perm.getValue());
+
+      return list.hashCode();
     }
 
     @Override
@@ -80963,7 +86705,7 @@
               break;
             case 4: // PERM
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-                struct.perm = TablePermission.findByValue(iprot.readI32());
+                struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
                 struct.setPermIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -81066,7 +86808,7 @@
           struct.setTableIsSet(true);
         }
         if (incoming.get(3)) {
-          struct.perm = TablePermission.findByValue(iprot.readI32());
+          struct.perm = org.apache.accumulo.proxy.thrift.TablePermission.findByValue(iprot.readI32());
           struct.setPermIsSet(true);
         }
       }
@@ -81387,7 +87129,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -81634,6 +87393,3627 @@
 
   }
 
+  public static class grantNamespacePermission_args implements org.apache.thrift.TBase<grantNamespacePermission_args, grantNamespacePermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<grantNamespacePermission_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("grantNamespacePermission_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)3);
+    private static final org.apache.thrift.protocol.TField PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", org.apache.thrift.protocol.TType.I32, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new grantNamespacePermission_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new grantNamespacePermission_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String user; // required
+    public String namespaceName; // required
+    /**
+     * 
+     * @see NamespacePermission
+     */
+    public NamespacePermission perm; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      USER((short)2, "user"),
+      NAMESPACE_NAME((short)3, "namespaceName"),
+      /**
+       * 
+       * @see NamespacePermission
+       */
+      PERM((short)4, "perm");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // USER
+            return USER;
+          case 3: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 4: // PERM
+            return PERM;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.USER, new org.apache.thrift.meta_data.FieldMetaData("user", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.PERM, new org.apache.thrift.meta_data.FieldMetaData("perm", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, NamespacePermission.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantNamespacePermission_args.class, metaDataMap);
+    }
+
+    public grantNamespacePermission_args() {
+    }
+
+    public grantNamespacePermission_args(
+      ByteBuffer login,
+      String user,
+      String namespaceName,
+      NamespacePermission perm)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.user = user;
+      this.namespaceName = namespaceName;
+      this.perm = perm;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public grantNamespacePermission_args(grantNamespacePermission_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetUser()) {
+        this.user = other.user;
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetPerm()) {
+        this.perm = other.perm;
+      }
+    }
+
+    public grantNamespacePermission_args deepCopy() {
+      return new grantNamespacePermission_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.user = null;
+      this.namespaceName = null;
+      this.perm = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public grantNamespacePermission_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public grantNamespacePermission_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getUser() {
+      return this.user;
+    }
+
+    public grantNamespacePermission_args setUser(String user) {
+      this.user = user;
+      return this;
+    }
+
+    public void unsetUser() {
+      this.user = null;
+    }
+
+    /** Returns true if field user is set (has been assigned a value) and false otherwise */
+    public boolean isSetUser() {
+      return this.user != null;
+    }
+
+    public void setUserIsSet(boolean value) {
+      if (!value) {
+        this.user = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public grantNamespacePermission_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    /**
+     * 
+     * @see NamespacePermission
+     */
+    public NamespacePermission getPerm() {
+      return this.perm;
+    }
+
+    /**
+     * 
+     * @see NamespacePermission
+     */
+    public grantNamespacePermission_args setPerm(NamespacePermission perm) {
+      this.perm = perm;
+      return this;
+    }
+
+    public void unsetPerm() {
+      this.perm = null;
+    }
+
+    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
+    public boolean isSetPerm() {
+      return this.perm != null;
+    }
+
+    public void setPermIsSet(boolean value) {
+      if (!value) {
+        this.perm = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case USER:
+        if (value == null) {
+          unsetUser();
+        } else {
+          setUser((String)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case PERM:
+        if (value == null) {
+          unsetPerm();
+        } else {
+          setPerm((NamespacePermission)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case USER:
+        return getUser();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case PERM:
+        return getPerm();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case USER:
+        return isSetUser();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case PERM:
+        return isSetPerm();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof grantNamespacePermission_args)
+        return this.equals((grantNamespacePermission_args)that);
+      return false;
+    }
+
+    public boolean equals(grantNamespacePermission_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_user = true && this.isSetUser();
+      boolean that_present_user = true && that.isSetUser();
+      if (this_present_user || that_present_user) {
+        if (!(this_present_user && that_present_user))
+          return false;
+        if (!this.user.equals(that.user))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_perm = true && this.isSetPerm();
+      boolean that_present_perm = true && that.isSetPerm();
+      if (this_present_perm || that_present_perm) {
+        if (!(this_present_perm && that_present_perm))
+          return false;
+        if (!this.perm.equals(that.perm))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_perm = true && (isSetPerm());
+      list.add(present_perm);
+      if (present_perm)
+        list.add(perm.getValue());
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(grantNamespacePermission_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetUser()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetPerm()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("grantNamespacePermission_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("user:");
+      if (this.user == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.user);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("perm:");
+      if (this.perm == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.perm);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class grantNamespacePermission_argsStandardSchemeFactory implements SchemeFactory {
+      public grantNamespacePermission_argsStandardScheme getScheme() {
+        return new grantNamespacePermission_argsStandardScheme();
+      }
+    }
+
+    private static class grantNamespacePermission_argsStandardScheme extends StandardScheme<grantNamespacePermission_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, grantNamespacePermission_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // USER
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.user = iprot.readString();
+                struct.setUserIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // PERM
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
+                struct.setPermIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, grantNamespacePermission_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.user != null) {
+          oprot.writeFieldBegin(USER_FIELD_DESC);
+          oprot.writeString(struct.user);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.perm != null) {
+          oprot.writeFieldBegin(PERM_FIELD_DESC);
+          oprot.writeI32(struct.perm.getValue());
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class grantNamespacePermission_argsTupleSchemeFactory implements SchemeFactory {
+      public grantNamespacePermission_argsTupleScheme getScheme() {
+        return new grantNamespacePermission_argsTupleScheme();
+      }
+    }
+
+    private static class grantNamespacePermission_argsTupleScheme extends TupleScheme<grantNamespacePermission_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, grantNamespacePermission_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetUser()) {
+          optionals.set(1);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(2);
+        }
+        if (struct.isSetPerm()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetUser()) {
+          oprot.writeString(struct.user);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetPerm()) {
+          oprot.writeI32(struct.perm.getValue());
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, grantNamespacePermission_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.user = iprot.readString();
+          struct.setUserIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
+          struct.setPermIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class grantNamespacePermission_result implements org.apache.thrift.TBase<grantNamespacePermission_result, grantNamespacePermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<grantNamespacePermission_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("grantNamespacePermission_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new grantNamespacePermission_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new grantNamespacePermission_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantNamespacePermission_result.class, metaDataMap);
+    }
+
+    public grantNamespacePermission_result() {
+    }
+
+    public grantNamespacePermission_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public grantNamespacePermission_result(grantNamespacePermission_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+    }
+
+    public grantNamespacePermission_result deepCopy() {
+      return new grantNamespacePermission_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public grantNamespacePermission_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public grantNamespacePermission_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof grantNamespacePermission_result)
+        return this.equals((grantNamespacePermission_result)that);
+      return false;
+    }
+
+    public boolean equals(grantNamespacePermission_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(grantNamespacePermission_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("grantNamespacePermission_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class grantNamespacePermission_resultStandardSchemeFactory implements SchemeFactory {
+      public grantNamespacePermission_resultStandardScheme getScheme() {
+        return new grantNamespacePermission_resultStandardScheme();
+      }
+    }
+
+    private static class grantNamespacePermission_resultStandardScheme extends StandardScheme<grantNamespacePermission_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, grantNamespacePermission_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, grantNamespacePermission_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class grantNamespacePermission_resultTupleSchemeFactory implements SchemeFactory {
+      public grantNamespacePermission_resultTupleScheme getScheme() {
+        return new grantNamespacePermission_resultTupleScheme();
+      }
+    }
+
+    private static class grantNamespacePermission_resultTupleScheme extends TupleScheme<grantNamespacePermission_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, grantNamespacePermission_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, grantNamespacePermission_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class hasNamespacePermission_args implements org.apache.thrift.TBase<hasNamespacePermission_args, hasNamespacePermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<hasNamespacePermission_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasNamespacePermission_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)3);
+    private static final org.apache.thrift.protocol.TField PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", org.apache.thrift.protocol.TType.I32, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new hasNamespacePermission_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new hasNamespacePermission_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String user; // required
+    public String namespaceName; // required
+    /**
+     * 
+     * @see NamespacePermission
+     */
+    public NamespacePermission perm; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      USER((short)2, "user"),
+      NAMESPACE_NAME((short)3, "namespaceName"),
+      /**
+       * 
+       * @see NamespacePermission
+       */
+      PERM((short)4, "perm");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // USER
+            return USER;
+          case 3: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 4: // PERM
+            return PERM;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.USER, new org.apache.thrift.meta_data.FieldMetaData("user", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.PERM, new org.apache.thrift.meta_data.FieldMetaData("perm", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, NamespacePermission.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasNamespacePermission_args.class, metaDataMap);
+    }
+
+    public hasNamespacePermission_args() {
+    }
+
+    public hasNamespacePermission_args(
+      ByteBuffer login,
+      String user,
+      String namespaceName,
+      NamespacePermission perm)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.user = user;
+      this.namespaceName = namespaceName;
+      this.perm = perm;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public hasNamespacePermission_args(hasNamespacePermission_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetUser()) {
+        this.user = other.user;
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetPerm()) {
+        this.perm = other.perm;
+      }
+    }
+
+    public hasNamespacePermission_args deepCopy() {
+      return new hasNamespacePermission_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.user = null;
+      this.namespaceName = null;
+      this.perm = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public hasNamespacePermission_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public hasNamespacePermission_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getUser() {
+      return this.user;
+    }
+
+    public hasNamespacePermission_args setUser(String user) {
+      this.user = user;
+      return this;
+    }
+
+    public void unsetUser() {
+      this.user = null;
+    }
+
+    /** Returns true if field user is set (has been assigned a value) and false otherwise */
+    public boolean isSetUser() {
+      return this.user != null;
+    }
+
+    public void setUserIsSet(boolean value) {
+      if (!value) {
+        this.user = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public hasNamespacePermission_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    /**
+     * 
+     * @see NamespacePermission
+     */
+    public NamespacePermission getPerm() {
+      return this.perm;
+    }
+
+    /**
+     * 
+     * @see NamespacePermission
+     */
+    public hasNamespacePermission_args setPerm(NamespacePermission perm) {
+      this.perm = perm;
+      return this;
+    }
+
+    public void unsetPerm() {
+      this.perm = null;
+    }
+
+    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
+    public boolean isSetPerm() {
+      return this.perm != null;
+    }
+
+    public void setPermIsSet(boolean value) {
+      if (!value) {
+        this.perm = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case USER:
+        if (value == null) {
+          unsetUser();
+        } else {
+          setUser((String)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case PERM:
+        if (value == null) {
+          unsetPerm();
+        } else {
+          setPerm((NamespacePermission)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case USER:
+        return getUser();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case PERM:
+        return getPerm();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case USER:
+        return isSetUser();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case PERM:
+        return isSetPerm();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof hasNamespacePermission_args)
+        return this.equals((hasNamespacePermission_args)that);
+      return false;
+    }
+
+    public boolean equals(hasNamespacePermission_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_user = true && this.isSetUser();
+      boolean that_present_user = true && that.isSetUser();
+      if (this_present_user || that_present_user) {
+        if (!(this_present_user && that_present_user))
+          return false;
+        if (!this.user.equals(that.user))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_perm = true && this.isSetPerm();
+      boolean that_present_perm = true && that.isSetPerm();
+      if (this_present_perm || that_present_perm) {
+        if (!(this_present_perm && that_present_perm))
+          return false;
+        if (!this.perm.equals(that.perm))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_perm = true && (isSetPerm());
+      list.add(present_perm);
+      if (present_perm)
+        list.add(perm.getValue());
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(hasNamespacePermission_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetUser()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetPerm()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("hasNamespacePermission_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("user:");
+      if (this.user == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.user);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("perm:");
+      if (this.perm == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.perm);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class hasNamespacePermission_argsStandardSchemeFactory implements SchemeFactory {
+      public hasNamespacePermission_argsStandardScheme getScheme() {
+        return new hasNamespacePermission_argsStandardScheme();
+      }
+    }
+
+    private static class hasNamespacePermission_argsStandardScheme extends StandardScheme<hasNamespacePermission_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, hasNamespacePermission_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // USER
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.user = iprot.readString();
+                struct.setUserIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // PERM
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
+                struct.setPermIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, hasNamespacePermission_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.user != null) {
+          oprot.writeFieldBegin(USER_FIELD_DESC);
+          oprot.writeString(struct.user);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.perm != null) {
+          oprot.writeFieldBegin(PERM_FIELD_DESC);
+          oprot.writeI32(struct.perm.getValue());
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class hasNamespacePermission_argsTupleSchemeFactory implements SchemeFactory {
+      public hasNamespacePermission_argsTupleScheme getScheme() {
+        return new hasNamespacePermission_argsTupleScheme();
+      }
+    }
+
+    private static class hasNamespacePermission_argsTupleScheme extends TupleScheme<hasNamespacePermission_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, hasNamespacePermission_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetUser()) {
+          optionals.set(1);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(2);
+        }
+        if (struct.isSetPerm()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetUser()) {
+          oprot.writeString(struct.user);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetPerm()) {
+          oprot.writeI32(struct.perm.getValue());
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, hasNamespacePermission_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.user = iprot.readString();
+          struct.setUserIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
+          struct.setPermIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class hasNamespacePermission_result implements org.apache.thrift.TBase<hasNamespacePermission_result, hasNamespacePermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<hasNamespacePermission_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasNamespacePermission_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new hasNamespacePermission_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new hasNamespacePermission_resultTupleSchemeFactory());
+    }
+
+    public boolean success; // required
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasNamespacePermission_result.class, metaDataMap);
+    }
+
+    public hasNamespacePermission_result() {
+    }
+
+    public hasNamespacePermission_result(
+      boolean success,
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public hasNamespacePermission_result(hasNamespacePermission_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+    }
+
+    public hasNamespacePermission_result deepCopy() {
+      return new hasNamespacePermission_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = false;
+      this.ouch1 = null;
+      this.ouch2 = null;
+    }
+
+    public boolean isSuccess() {
+      return this.success;
+    }
+
+    public hasNamespacePermission_result setSuccess(boolean success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public hasNamespacePermission_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public hasNamespacePermission_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Boolean)value);
+        }
+        break;
+
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return isSuccess();
+
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof hasNamespacePermission_result)
+        return this.equals((hasNamespacePermission_result)that);
+      return false;
+    }
+
+    public boolean equals(hasNamespacePermission_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true;
+      boolean that_present_success = true;
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (this.success != that.success)
+          return false;
+      }
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(hasNamespacePermission_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("hasNamespacePermission_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class hasNamespacePermission_resultStandardSchemeFactory implements SchemeFactory {
+      public hasNamespacePermission_resultStandardScheme getScheme() {
+        return new hasNamespacePermission_resultStandardScheme();
+      }
+    }
+
+    private static class hasNamespacePermission_resultStandardScheme extends StandardScheme<hasNamespacePermission_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, hasNamespacePermission_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
+                struct.success = iprot.readBool();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, hasNamespacePermission_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeBool(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class hasNamespacePermission_resultTupleSchemeFactory implements SchemeFactory {
+      public hasNamespacePermission_resultTupleScheme getScheme() {
+        return new hasNamespacePermission_resultTupleScheme();
+      }
+    }
+
+    private static class hasNamespacePermission_resultTupleScheme extends TupleScheme<hasNamespacePermission_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, hasNamespacePermission_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch1()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetSuccess()) {
+          oprot.writeBool(struct.success);
+        }
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, hasNamespacePermission_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.success = iprot.readBool();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class revokeNamespacePermission_args implements org.apache.thrift.TBase<revokeNamespacePermission_args, revokeNamespacePermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<revokeNamespacePermission_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeNamespacePermission_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)3);
+    private static final org.apache.thrift.protocol.TField PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", org.apache.thrift.protocol.TType.I32, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new revokeNamespacePermission_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new revokeNamespacePermission_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String user; // required
+    public String namespaceName; // required
+    /**
+     * 
+     * @see NamespacePermission
+     */
+    public NamespacePermission perm; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      USER((short)2, "user"),
+      NAMESPACE_NAME((short)3, "namespaceName"),
+      /**
+       * 
+       * @see NamespacePermission
+       */
+      PERM((short)4, "perm");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // USER
+            return USER;
+          case 3: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 4: // PERM
+            return PERM;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.USER, new org.apache.thrift.meta_data.FieldMetaData("user", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.PERM, new org.apache.thrift.meta_data.FieldMetaData("perm", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, NamespacePermission.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeNamespacePermission_args.class, metaDataMap);
+    }
+
+    public revokeNamespacePermission_args() {
+    }
+
+    public revokeNamespacePermission_args(
+      ByteBuffer login,
+      String user,
+      String namespaceName,
+      NamespacePermission perm)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.user = user;
+      this.namespaceName = namespaceName;
+      this.perm = perm;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public revokeNamespacePermission_args(revokeNamespacePermission_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetUser()) {
+        this.user = other.user;
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetPerm()) {
+        this.perm = other.perm;
+      }
+    }
+
+    public revokeNamespacePermission_args deepCopy() {
+      return new revokeNamespacePermission_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.user = null;
+      this.namespaceName = null;
+      this.perm = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public revokeNamespacePermission_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public revokeNamespacePermission_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getUser() {
+      return this.user;
+    }
+
+    public revokeNamespacePermission_args setUser(String user) {
+      this.user = user;
+      return this;
+    }
+
+    public void unsetUser() {
+      this.user = null;
+    }
+
+    /** Returns true if field user is set (has been assigned a value) and false otherwise */
+    public boolean isSetUser() {
+      return this.user != null;
+    }
+
+    public void setUserIsSet(boolean value) {
+      if (!value) {
+        this.user = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public revokeNamespacePermission_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    /**
+     * 
+     * @see NamespacePermission
+     */
+    public NamespacePermission getPerm() {
+      return this.perm;
+    }
+
+    /**
+     * 
+     * @see NamespacePermission
+     */
+    public revokeNamespacePermission_args setPerm(NamespacePermission perm) {
+      this.perm = perm;
+      return this;
+    }
+
+    public void unsetPerm() {
+      this.perm = null;
+    }
+
+    /** Returns true if field perm is set (has been assigned a value) and false otherwise */
+    public boolean isSetPerm() {
+      return this.perm != null;
+    }
+
+    public void setPermIsSet(boolean value) {
+      if (!value) {
+        this.perm = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case USER:
+        if (value == null) {
+          unsetUser();
+        } else {
+          setUser((String)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case PERM:
+        if (value == null) {
+          unsetPerm();
+        } else {
+          setPerm((NamespacePermission)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case USER:
+        return getUser();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case PERM:
+        return getPerm();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case USER:
+        return isSetUser();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case PERM:
+        return isSetPerm();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof revokeNamespacePermission_args)
+        return this.equals((revokeNamespacePermission_args)that);
+      return false;
+    }
+
+    public boolean equals(revokeNamespacePermission_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_user = true && this.isSetUser();
+      boolean that_present_user = true && that.isSetUser();
+      if (this_present_user || that_present_user) {
+        if (!(this_present_user && that_present_user))
+          return false;
+        if (!this.user.equals(that.user))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_perm = true && this.isSetPerm();
+      boolean that_present_perm = true && that.isSetPerm();
+      if (this_present_perm || that_present_perm) {
+        if (!(this_present_perm && that_present_perm))
+          return false;
+        if (!this.perm.equals(that.perm))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_user = true && (isSetUser());
+      list.add(present_user);
+      if (present_user)
+        list.add(user);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_perm = true && (isSetPerm());
+      list.add(present_perm);
+      if (present_perm)
+        list.add(perm.getValue());
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(revokeNamespacePermission_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetUser()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetPerm()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.perm, other.perm);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("revokeNamespacePermission_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("user:");
+      if (this.user == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.user);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("perm:");
+      if (this.perm == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.perm);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class revokeNamespacePermission_argsStandardSchemeFactory implements SchemeFactory {
+      public revokeNamespacePermission_argsStandardScheme getScheme() {
+        return new revokeNamespacePermission_argsStandardScheme();
+      }
+    }
+
+    private static class revokeNamespacePermission_argsStandardScheme extends StandardScheme<revokeNamespacePermission_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, revokeNamespacePermission_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // USER
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.user = iprot.readString();
+                struct.setUserIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // PERM
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
+                struct.setPermIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeNamespacePermission_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.user != null) {
+          oprot.writeFieldBegin(USER_FIELD_DESC);
+          oprot.writeString(struct.user);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.perm != null) {
+          oprot.writeFieldBegin(PERM_FIELD_DESC);
+          oprot.writeI32(struct.perm.getValue());
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class revokeNamespacePermission_argsTupleSchemeFactory implements SchemeFactory {
+      public revokeNamespacePermission_argsTupleScheme getScheme() {
+        return new revokeNamespacePermission_argsTupleScheme();
+      }
+    }
+
+    private static class revokeNamespacePermission_argsTupleScheme extends TupleScheme<revokeNamespacePermission_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, revokeNamespacePermission_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetUser()) {
+          optionals.set(1);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(2);
+        }
+        if (struct.isSetPerm()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetUser()) {
+          oprot.writeString(struct.user);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetPerm()) {
+          oprot.writeI32(struct.perm.getValue());
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, revokeNamespacePermission_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.user = iprot.readString();
+          struct.setUserIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.perm = org.apache.accumulo.proxy.thrift.NamespacePermission.findByValue(iprot.readI32());
+          struct.setPermIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class revokeNamespacePermission_result implements org.apache.thrift.TBase<revokeNamespacePermission_result, revokeNamespacePermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<revokeNamespacePermission_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeNamespacePermission_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new revokeNamespacePermission_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new revokeNamespacePermission_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeNamespacePermission_result.class, metaDataMap);
+    }
+
+    public revokeNamespacePermission_result() {
+    }
+
+    public revokeNamespacePermission_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public revokeNamespacePermission_result(revokeNamespacePermission_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+    }
+
+    public revokeNamespacePermission_result deepCopy() {
+      return new revokeNamespacePermission_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public revokeNamespacePermission_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public revokeNamespacePermission_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof revokeNamespacePermission_result)
+        return this.equals((revokeNamespacePermission_result)that);
+      return false;
+    }
+
+    public boolean equals(revokeNamespacePermission_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(revokeNamespacePermission_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("revokeNamespacePermission_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class revokeNamespacePermission_resultStandardSchemeFactory implements SchemeFactory {
+      public revokeNamespacePermission_resultStandardScheme getScheme() {
+        return new revokeNamespacePermission_resultStandardScheme();
+      }
+    }
+
+    private static class revokeNamespacePermission_resultStandardScheme extends StandardScheme<revokeNamespacePermission_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, revokeNamespacePermission_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeNamespacePermission_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class revokeNamespacePermission_resultTupleSchemeFactory implements SchemeFactory {
+      public revokeNamespacePermission_resultTupleScheme getScheme() {
+        return new revokeNamespacePermission_resultTupleScheme();
+      }
+    }
+
+    private static class revokeNamespacePermission_resultTupleScheme extends TupleScheme<revokeNamespacePermission_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, revokeNamespacePermission_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, revokeNamespacePermission_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+      }
+    }
+
+  }
+
   public static class createBatchScanner_args implements org.apache.thrift.TBase<createBatchScanner_args, createBatchScanner_args._Fields>, java.io.Serializable, Cloneable, Comparable<createBatchScanner_args>   {
     private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createBatchScanner_args");
 
@@ -81738,7 +91118,7 @@
       BatchScanOptions options)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.options = options;
     }
@@ -81749,7 +91129,6 @@
     public createBatchScanner_args(createBatchScanner_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -81776,16 +91155,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createBatchScanner_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public createBatchScanner_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -81958,7 +91337,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_options = true && (isSetOptions());
+      list.add(present_options);
+      if (present_options)
+        list.add(options);
+
+      return list.hashCode();
     }
 
     @Override
@@ -82576,7 +91972,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -82968,7 +92386,7 @@
       ScanOptions options)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.options = options;
     }
@@ -82979,7 +92397,6 @@
     public createScanner_args(createScanner_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -83006,16 +92423,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createScanner_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public createScanner_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -83188,7 +92605,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_options = true && (isSetOptions());
+      list.add(present_options);
+      if (present_options)
+        list.add(options);
+
+      return list.hashCode();
     }
 
     @Override
@@ -83806,7 +93240,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -84289,7 +93745,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_scanner = true && (isSetScanner());
+      list.add(present_scanner);
+      if (present_scanner)
+        list.add(scanner);
+
+      return list.hashCode();
     }
 
     @Override
@@ -84644,7 +94107,7 @@
     public Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
-        return Boolean.valueOf(isSuccess());
+        return isSuccess();
 
       case OUCH1:
         return getOuch1();
@@ -84704,7 +94167,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      return list.hashCode();
     }
 
     @Override
@@ -85099,7 +94574,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_scanner = true && (isSetScanner());
+      list.add(present_scanner);
+      if (present_scanner)
+        list.add(scanner);
+
+      return list.hashCode();
     }
 
     @Override
@@ -85630,7 +95112,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -86122,7 +95626,7 @@
         return getScanner();
 
       case K:
-        return Integer.valueOf(getK());
+        return getK();
 
       }
       throw new IllegalStateException();
@@ -86179,7 +95683,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_scanner = true && (isSetScanner());
+      list.add(present_scanner);
+      if (present_scanner)
+        list.add(scanner);
+
+      boolean present_k = true;
+      list.add(present_k);
+      if (present_k)
+        list.add(k);
+
+      return list.hashCode();
     }
 
     @Override
@@ -86747,7 +96263,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -87235,7 +96773,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_scanner = true && (isSetScanner());
+      list.add(present_scanner);
+      if (present_scanner)
+        list.add(scanner);
+
+      return list.hashCode();
     }
 
     @Override
@@ -87589,7 +97134,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      return list.hashCode();
     }
 
     @Override
@@ -87857,7 +97409,7 @@
       Map<ByteBuffer,List<ColumnUpdate>> cells)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.cells = cells;
     }
@@ -87868,7 +97420,6 @@
     public updateAndFlush_args(updateAndFlush_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -87881,7 +97432,6 @@
           List<ColumnUpdate> other_element_value = other_element.getValue();
 
           ByteBuffer __this__cells_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
-;
 
           List<ColumnUpdate> __this__cells_copy_value = new ArrayList<ColumnUpdate>(other_element_value.size());
           for (ColumnUpdate other_element_value_element : other_element_value) {
@@ -87911,16 +97461,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public updateAndFlush_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public updateAndFlush_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -88104,7 +97654,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_cells = true && (isSetCells());
+      list.add(present_cells);
+      if (present_cells)
+        list.add(cells);
+
+      return list.hashCode();
     }
 
     @Override
@@ -88252,24 +97819,24 @@
                 {
                   org.apache.thrift.protocol.TMap _map442 = iprot.readMapBegin();
                   struct.cells = new HashMap<ByteBuffer,List<ColumnUpdate>>(2*_map442.size);
-                  for (int _i443 = 0; _i443 < _map442.size; ++_i443)
+                  ByteBuffer _key443;
+                  List<ColumnUpdate> _val444;
+                  for (int _i445 = 0; _i445 < _map442.size; ++_i445)
                   {
-                    ByteBuffer _key444;
-                    List<ColumnUpdate> _val445;
-                    _key444 = iprot.readBinary();
+                    _key443 = iprot.readBinary();
                     {
                       org.apache.thrift.protocol.TList _list446 = iprot.readListBegin();
-                      _val445 = new ArrayList<ColumnUpdate>(_list446.size);
-                      for (int _i447 = 0; _i447 < _list446.size; ++_i447)
+                      _val444 = new ArrayList<ColumnUpdate>(_list446.size);
+                      ColumnUpdate _elem447;
+                      for (int _i448 = 0; _i448 < _list446.size; ++_i448)
                       {
-                        ColumnUpdate _elem448;
-                        _elem448 = new ColumnUpdate();
-                        _elem448.read(iprot);
-                        _val445.add(_elem448);
+                        _elem447 = new ColumnUpdate();
+                        _elem447.read(iprot);
+                        _val444.add(_elem447);
                       }
                       iprot.readListEnd();
                     }
-                    struct.cells.put(_key444, _val445);
+                    struct.cells.put(_key443, _val444);
                   }
                   iprot.readMapEnd();
                 }
@@ -88391,23 +97958,23 @@
           {
             org.apache.thrift.protocol.TMap _map453 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, iprot.readI32());
             struct.cells = new HashMap<ByteBuffer,List<ColumnUpdate>>(2*_map453.size);
-            for (int _i454 = 0; _i454 < _map453.size; ++_i454)
+            ByteBuffer _key454;
+            List<ColumnUpdate> _val455;
+            for (int _i456 = 0; _i456 < _map453.size; ++_i456)
             {
-              ByteBuffer _key455;
-              List<ColumnUpdate> _val456;
-              _key455 = iprot.readBinary();
+              _key454 = iprot.readBinary();
               {
                 org.apache.thrift.protocol.TList _list457 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
-                _val456 = new ArrayList<ColumnUpdate>(_list457.size);
-                for (int _i458 = 0; _i458 < _list457.size; ++_i458)
+                _val455 = new ArrayList<ColumnUpdate>(_list457.size);
+                ColumnUpdate _elem458;
+                for (int _i459 = 0; _i459 < _list457.size; ++_i459)
                 {
-                  ColumnUpdate _elem459;
-                  _elem459 = new ColumnUpdate();
-                  _elem459.read(iprot);
-                  _val456.add(_elem459);
+                  _elem458 = new ColumnUpdate();
+                  _elem458.read(iprot);
+                  _val455.add(_elem458);
                 }
               }
-              struct.cells.put(_key455, _val456);
+              struct.cells.put(_key454, _val455);
             }
           }
           struct.setCellsIsSet(true);
@@ -88789,7 +98356,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_outch1 = true && (isSetOutch1());
+      list.add(present_outch1);
+      if (present_outch1)
+        list.add(outch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      boolean present_ouch4 = true && (isSetOuch4());
+      list.add(present_ouch4);
+      if (present_ouch4)
+        list.add(ouch4);
+
+      return list.hashCode();
     }
 
     @Override
@@ -89183,7 +98772,7 @@
       WriterOptions opts)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.opts = opts;
     }
@@ -89194,7 +98783,6 @@
     public createWriter_args(createWriter_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -89221,16 +98809,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createWriter_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public createWriter_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -89403,7 +98991,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_opts = true && (isSetOpts());
+      list.add(present_opts);
+      if (present_opts)
+        list.add(opts);
+
+      return list.hashCode();
     }
 
     @Override
@@ -90021,7 +99626,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_outch1 = true && (isSetOutch1());
+      list.add(present_outch1);
+      if (present_outch1)
+        list.add(outch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -90427,7 +100054,6 @@
           List<ColumnUpdate> other_element_value = other_element.getValue();
 
           ByteBuffer __this__cells_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
-;
 
           List<ColumnUpdate> __this__cells_copy_value = new ArrayList<ColumnUpdate>(other_element_value.size());
           for (ColumnUpdate other_element_value_element : other_element_value) {
@@ -90593,7 +100219,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_writer = true && (isSetWriter());
+      list.add(present_writer);
+      if (present_writer)
+        list.add(writer);
+
+      boolean present_cells = true && (isSetCells());
+      list.add(present_cells);
+      if (present_cells)
+        list.add(cells);
+
+      return list.hashCode();
     }
 
     @Override
@@ -90715,24 +100353,24 @@
                 {
                   org.apache.thrift.protocol.TMap _map460 = iprot.readMapBegin();
                   struct.cells = new HashMap<ByteBuffer,List<ColumnUpdate>>(2*_map460.size);
-                  for (int _i461 = 0; _i461 < _map460.size; ++_i461)
+                  ByteBuffer _key461;
+                  List<ColumnUpdate> _val462;
+                  for (int _i463 = 0; _i463 < _map460.size; ++_i463)
                   {
-                    ByteBuffer _key462;
-                    List<ColumnUpdate> _val463;
-                    _key462 = iprot.readBinary();
+                    _key461 = iprot.readBinary();
                     {
                       org.apache.thrift.protocol.TList _list464 = iprot.readListBegin();
-                      _val463 = new ArrayList<ColumnUpdate>(_list464.size);
-                      for (int _i465 = 0; _i465 < _list464.size; ++_i465)
+                      _val462 = new ArrayList<ColumnUpdate>(_list464.size);
+                      ColumnUpdate _elem465;
+                      for (int _i466 = 0; _i466 < _list464.size; ++_i466)
                       {
-                        ColumnUpdate _elem466;
-                        _elem466 = new ColumnUpdate();
-                        _elem466.read(iprot);
-                        _val463.add(_elem466);
+                        _elem465 = new ColumnUpdate();
+                        _elem465.read(iprot);
+                        _val462.add(_elem465);
                       }
                       iprot.readListEnd();
                     }
-                    struct.cells.put(_key462, _val463);
+                    struct.cells.put(_key461, _val462);
                   }
                   iprot.readMapEnd();
                 }
@@ -90839,23 +100477,23 @@
           {
             org.apache.thrift.protocol.TMap _map471 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, iprot.readI32());
             struct.cells = new HashMap<ByteBuffer,List<ColumnUpdate>>(2*_map471.size);
-            for (int _i472 = 0; _i472 < _map471.size; ++_i472)
+            ByteBuffer _key472;
+            List<ColumnUpdate> _val473;
+            for (int _i474 = 0; _i474 < _map471.size; ++_i474)
             {
-              ByteBuffer _key473;
-              List<ColumnUpdate> _val474;
-              _key473 = iprot.readBinary();
+              _key472 = iprot.readBinary();
               {
                 org.apache.thrift.protocol.TList _list475 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
-                _val474 = new ArrayList<ColumnUpdate>(_list475.size);
-                for (int _i476 = 0; _i476 < _list475.size; ++_i476)
+                _val473 = new ArrayList<ColumnUpdate>(_list475.size);
+                ColumnUpdate _elem476;
+                for (int _i477 = 0; _i477 < _list475.size; ++_i477)
                 {
-                  ColumnUpdate _elem477;
-                  _elem477 = new ColumnUpdate();
-                  _elem477.read(iprot);
-                  _val474.add(_elem477);
+                  _elem476 = new ColumnUpdate();
+                  _elem476.read(iprot);
+                  _val473.add(_elem476);
                 }
               }
-              struct.cells.put(_key473, _val474);
+              struct.cells.put(_key472, _val473);
             }
           }
           struct.setCellsIsSet(true);
@@ -91060,7 +100698,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_writer = true && (isSetWriter());
+      list.add(present_writer);
+      if (present_writer)
+        list.add(writer);
+
+      return list.hashCode();
     }
 
     @Override
@@ -91473,7 +101118,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -91872,7 +101529,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_writer = true && (isSetWriter());
+      list.add(present_writer);
+      if (present_writer)
+        list.add(writer);
+
+      return list.hashCode();
     }
 
     @Override
@@ -92285,7 +101949,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
     }
 
     @Override
@@ -92601,9 +102277,9 @@
       ConditionalUpdates updates)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
-      this.row = row;
+      this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
       this.updates = updates;
     }
 
@@ -92613,14 +102289,12 @@
     public updateRowConditionally_args(updateRowConditionally_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
       }
       if (other.isSetRow()) {
         this.row = org.apache.thrift.TBaseHelper.copyBinary(other.row);
-;
       }
       if (other.isSetUpdates()) {
         this.updates = new ConditionalUpdates(other.updates);
@@ -92645,16 +102319,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public updateRowConditionally_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public updateRowConditionally_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -92703,16 +102377,16 @@
     }
 
     public ByteBuffer bufferForRow() {
-      return row;
+      return org.apache.thrift.TBaseHelper.copyBinary(row);
     }
 
     public updateRowConditionally_args setRow(byte[] row) {
-      setRow(row == null ? (ByteBuffer)null : ByteBuffer.wrap(row));
+      this.row = row == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(row, row.length));
       return this;
     }
 
     public updateRowConditionally_args setRow(ByteBuffer row) {
-      this.row = row;
+      this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
       return this;
     }
 
@@ -92883,7 +102557,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_row = true && (isSetRow());
+      list.add(present_row);
+      if (present_row)
+        list.add(row);
+
+      boolean present_updates = true && (isSetUpdates());
+      list.add(present_updates);
+      if (present_updates)
+        list.add(updates);
+
+      return list.hashCode();
     }
 
     @Override
@@ -93558,7 +103254,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success.getValue());
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -93705,7 +103423,7 @@
           switch (schemeField.id) {
             case 0: // SUCCESS
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-                struct.success = ConditionalStatus.findByValue(iprot.readI32());
+                struct.success = org.apache.accumulo.proxy.thrift.ConditionalStatus.findByValue(iprot.readI32());
                 struct.setSuccessIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -93823,7 +103541,7 @@
         TTupleProtocol iprot = (TTupleProtocol) prot;
         BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
-          struct.success = ConditionalStatus.findByValue(iprot.readI32());
+          struct.success = org.apache.accumulo.proxy.thrift.ConditionalStatus.findByValue(iprot.readI32());
           struct.setSuccessIsSet(true);
         }
         if (incoming.get(1)) {
@@ -93950,7 +103668,7 @@
       ConditionalWriterOptions options)
     {
       this();
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       this.tableName = tableName;
       this.options = options;
     }
@@ -93961,7 +103679,6 @@
     public createConditionalWriter_args(createConditionalWriter_args other) {
       if (other.isSetLogin()) {
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
-;
       }
       if (other.isSetTableName()) {
         this.tableName = other.tableName;
@@ -93988,16 +103705,16 @@
     }
 
     public ByteBuffer bufferForLogin() {
-      return login;
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createConditionalWriter_args setLogin(byte[] login) {
-      setLogin(login == null ? (ByteBuffer)null : ByteBuffer.wrap(login));
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
       return this;
     }
 
     public createConditionalWriter_args setLogin(ByteBuffer login) {
-      this.login = login;
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
 
@@ -94170,7 +103887,24 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_tableName = true && (isSetTableName());
+      list.add(present_tableName);
+      if (present_tableName)
+        list.add(tableName);
+
+      boolean present_options = true && (isSetOptions());
+      list.add(present_options);
+      if (present_options)
+        list.add(options);
+
+      return list.hashCode();
     }
 
     @Override
@@ -94788,7 +104522,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -95193,7 +104949,6 @@
           ConditionalUpdates other_element_value = other_element.getValue();
 
           ByteBuffer __this__updates_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
-;
 
           ConditionalUpdates __this__updates_copy_value = new ConditionalUpdates(other_element_value);
 
@@ -95356,7 +105111,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_conditionalWriter = true && (isSetConditionalWriter());
+      list.add(present_conditionalWriter);
+      if (present_conditionalWriter)
+        list.add(conditionalWriter);
+
+      boolean present_updates = true && (isSetUpdates());
+      list.add(present_updates);
+      if (present_updates)
+        list.add(updates);
+
+      return list.hashCode();
     }
 
     @Override
@@ -95478,14 +105245,14 @@
                 {
                   org.apache.thrift.protocol.TMap _map478 = iprot.readMapBegin();
                   struct.updates = new HashMap<ByteBuffer,ConditionalUpdates>(2*_map478.size);
-                  for (int _i479 = 0; _i479 < _map478.size; ++_i479)
+                  ByteBuffer _key479;
+                  ConditionalUpdates _val480;
+                  for (int _i481 = 0; _i481 < _map478.size; ++_i481)
                   {
-                    ByteBuffer _key480;
-                    ConditionalUpdates _val481;
-                    _key480 = iprot.readBinary();
-                    _val481 = new ConditionalUpdates();
-                    _val481.read(iprot);
-                    struct.updates.put(_key480, _val481);
+                    _key479 = iprot.readBinary();
+                    _val480 = new ConditionalUpdates();
+                    _val480.read(iprot);
+                    struct.updates.put(_key479, _val480);
                   }
                   iprot.readMapEnd();
                 }
@@ -95579,14 +105346,14 @@
           {
             org.apache.thrift.protocol.TMap _map484 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
             struct.updates = new HashMap<ByteBuffer,ConditionalUpdates>(2*_map484.size);
-            for (int _i485 = 0; _i485 < _map484.size; ++_i485)
+            ByteBuffer _key485;
+            ConditionalUpdates _val486;
+            for (int _i487 = 0; _i487 < _map484.size; ++_i487)
             {
-              ByteBuffer _key486;
-              ConditionalUpdates _val487;
-              _key486 = iprot.readBinary();
-              _val487 = new ConditionalUpdates();
-              _val487.read(iprot);
-              struct.updates.put(_key486, _val487);
+              _key485 = iprot.readBinary();
+              _val486 = new ConditionalUpdates();
+              _val486.read(iprot);
+              struct.updates.put(_key485, _val486);
             }
           }
           struct.setUpdatesIsSet(true);
@@ -95728,7 +105495,6 @@
           ConditionalStatus other_element_value = other_element.getValue();
 
           ByteBuffer __this__success_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
-;
 
           ConditionalStatus __this__success_copy_value = other_element_value;
 
@@ -95994,7 +105760,29 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
     }
 
     @Override
@@ -96144,13 +105932,13 @@
                 {
                   org.apache.thrift.protocol.TMap _map488 = iprot.readMapBegin();
                   struct.success = new HashMap<ByteBuffer,ConditionalStatus>(2*_map488.size);
-                  for (int _i489 = 0; _i489 < _map488.size; ++_i489)
+                  ByteBuffer _key489;
+                  ConditionalStatus _val490;
+                  for (int _i491 = 0; _i491 < _map488.size; ++_i491)
                   {
-                    ByteBuffer _key490;
-                    ConditionalStatus _val491;
-                    _key490 = iprot.readBinary();
-                    _val491 = ConditionalStatus.findByValue(iprot.readI32());
-                    struct.success.put(_key490, _val491);
+                    _key489 = iprot.readBinary();
+                    _val490 = org.apache.accumulo.proxy.thrift.ConditionalStatus.findByValue(iprot.readI32());
+                    struct.success.put(_key489, _val490);
                   }
                   iprot.readMapEnd();
                 }
@@ -96289,13 +106077,13 @@
           {
             org.apache.thrift.protocol.TMap _map494 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, iprot.readI32());
             struct.success = new HashMap<ByteBuffer,ConditionalStatus>(2*_map494.size);
-            for (int _i495 = 0; _i495 < _map494.size; ++_i495)
+            ByteBuffer _key495;
+            ConditionalStatus _val496;
+            for (int _i497 = 0; _i497 < _map494.size; ++_i497)
             {
-              ByteBuffer _key496;
-              ConditionalStatus _val497;
-              _key496 = iprot.readBinary();
-              _val497 = ConditionalStatus.findByValue(iprot.readI32());
-              struct.success.put(_key496, _val497);
+              _key495 = iprot.readBinary();
+              _val496 = org.apache.accumulo.proxy.thrift.ConditionalStatus.findByValue(iprot.readI32());
+              struct.success.put(_key495, _val496);
             }
           }
           struct.setSuccessIsSet(true);
@@ -96515,7 +106303,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_conditionalWriter = true && (isSetConditionalWriter());
+      list.add(present_conditionalWriter);
+      if (present_conditionalWriter)
+        list.add(conditionalWriter);
+
+      return list.hashCode();
     }
 
     @Override
@@ -96804,7 +106599,9 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      return list.hashCode();
     }
 
     @Override
@@ -97008,7 +106805,7 @@
       ByteBuffer row)
     {
       this();
-      this.row = row;
+      this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
     }
 
     /**
@@ -97017,7 +106814,6 @@
     public getRowRange_args(getRowRange_args other) {
       if (other.isSetRow()) {
         this.row = org.apache.thrift.TBaseHelper.copyBinary(other.row);
-;
       }
     }
 
@@ -97036,16 +106832,16 @@
     }
 
     public ByteBuffer bufferForRow() {
-      return row;
+      return org.apache.thrift.TBaseHelper.copyBinary(row);
     }
 
     public getRowRange_args setRow(byte[] row) {
-      setRow(row == null ? (ByteBuffer)null : ByteBuffer.wrap(row));
+      this.row = row == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(row, row.length));
       return this;
     }
 
     public getRowRange_args setRow(ByteBuffer row) {
-      this.row = row;
+      this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
       return this;
     }
 
@@ -97126,7 +106922,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_row = true && (isSetRow());
+      list.add(present_row);
+      if (present_row)
+        list.add(row);
+
+      return list.hashCode();
     }
 
     @Override
@@ -97480,7 +107283,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      return list.hashCode();
     }
 
     @Override
@@ -97914,7 +107724,19 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_key = true && (isSetKey());
+      list.add(present_key);
+      if (present_key)
+        list.add(key);
+
+      boolean present_part = true && (isSetPart());
+      list.add(present_part);
+      if (present_part)
+        list.add(part.getValue());
+
+      return list.hashCode();
     }
 
     @Override
@@ -98037,7 +107859,7 @@
               break;
             case 2: // PART
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-                struct.part = PartialKey.findByValue(iprot.readI32());
+                struct.part = org.apache.accumulo.proxy.thrift.PartialKey.findByValue(iprot.readI32());
                 struct.setPartIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -98111,7 +107933,7 @@
           struct.setKeyIsSet(true);
         }
         if (incoming.get(1)) {
-          struct.part = PartialKey.findByValue(iprot.readI32());
+          struct.part = org.apache.accumulo.proxy.thrift.PartialKey.findByValue(iprot.readI32());
           struct.setPartIsSet(true);
         }
       }
@@ -98314,7 +108136,14 @@
 
     @Override
     public int hashCode() {
-      return 0;
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      return list.hashCode();
     }
 
     @Override
@@ -98478,4 +108307,22973 @@
 
   }
 
+  public static class systemNamespace_args implements org.apache.thrift.TBase<systemNamespace_args, systemNamespace_args._Fields>, java.io.Serializable, Cloneable, Comparable<systemNamespace_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("systemNamespace_args");
+
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new systemNamespace_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new systemNamespace_argsTupleSchemeFactory());
+    }
+
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+;
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(systemNamespace_args.class, metaDataMap);
+    }
+
+    public systemNamespace_args() {
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public systemNamespace_args(systemNamespace_args other) {
+    }
+
+    public systemNamespace_args deepCopy() {
+      return new systemNamespace_args(this);
+    }
+
+    @Override
+    public void clear() {
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof systemNamespace_args)
+        return this.equals((systemNamespace_args)that);
+      return false;
+    }
+
+    public boolean equals(systemNamespace_args that) {
+      if (that == null)
+        return false;
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(systemNamespace_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("systemNamespace_args(");
+      boolean first = true;
+
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class systemNamespace_argsStandardSchemeFactory implements SchemeFactory {
+      public systemNamespace_argsStandardScheme getScheme() {
+        return new systemNamespace_argsStandardScheme();
+      }
+    }
+
+    private static class systemNamespace_argsStandardScheme extends StandardScheme<systemNamespace_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, systemNamespace_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, systemNamespace_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class systemNamespace_argsTupleSchemeFactory implements SchemeFactory {
+      public systemNamespace_argsTupleScheme getScheme() {
+        return new systemNamespace_argsTupleScheme();
+      }
+    }
+
+    private static class systemNamespace_argsTupleScheme extends TupleScheme<systemNamespace_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, systemNamespace_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, systemNamespace_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+      }
+    }
+
+  }
+
+  public static class systemNamespace_result implements org.apache.thrift.TBase<systemNamespace_result, systemNamespace_result._Fields>, java.io.Serializable, Cloneable, Comparable<systemNamespace_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("systemNamespace_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new systemNamespace_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new systemNamespace_resultTupleSchemeFactory());
+    }
+
+    public String success; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(systemNamespace_result.class, metaDataMap);
+    }
+
+    public systemNamespace_result() {
+    }
+
+    public systemNamespace_result(
+      String success)
+    {
+      this();
+      this.success = success;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public systemNamespace_result(systemNamespace_result other) {
+      if (other.isSetSuccess()) {
+        this.success = other.success;
+      }
+    }
+
+    public systemNamespace_result deepCopy() {
+      return new systemNamespace_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+    }
+
+    public String getSuccess() {
+      return this.success;
+    }
+
+    public systemNamespace_result setSuccess(String success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof systemNamespace_result)
+        return this.equals((systemNamespace_result)that);
+      return false;
+    }
+
+    public boolean equals(systemNamespace_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(systemNamespace_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("systemNamespace_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class systemNamespace_resultStandardSchemeFactory implements SchemeFactory {
+      public systemNamespace_resultStandardScheme getScheme() {
+        return new systemNamespace_resultStandardScheme();
+      }
+    }
+
+    private static class systemNamespace_resultStandardScheme extends StandardScheme<systemNamespace_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, systemNamespace_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.success = iprot.readString();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, systemNamespace_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeString(struct.success);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class systemNamespace_resultTupleSchemeFactory implements SchemeFactory {
+      public systemNamespace_resultTupleScheme getScheme() {
+        return new systemNamespace_resultTupleScheme();
+      }
+    }
+
+    private static class systemNamespace_resultTupleScheme extends TupleScheme<systemNamespace_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, systemNamespace_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetSuccess()) {
+          oprot.writeString(struct.success);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, systemNamespace_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.success = iprot.readString();
+          struct.setSuccessIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class defaultNamespace_args implements org.apache.thrift.TBase<defaultNamespace_args, defaultNamespace_args._Fields>, java.io.Serializable, Cloneable, Comparable<defaultNamespace_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("defaultNamespace_args");
+
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new defaultNamespace_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new defaultNamespace_argsTupleSchemeFactory());
+    }
+
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+;
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(defaultNamespace_args.class, metaDataMap);
+    }
+
+    public defaultNamespace_args() {
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public defaultNamespace_args(defaultNamespace_args other) {
+    }
+
+    public defaultNamespace_args deepCopy() {
+      return new defaultNamespace_args(this);
+    }
+
+    @Override
+    public void clear() {
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof defaultNamespace_args)
+        return this.equals((defaultNamespace_args)that);
+      return false;
+    }
+
+    public boolean equals(defaultNamespace_args that) {
+      if (that == null)
+        return false;
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(defaultNamespace_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("defaultNamespace_args(");
+      boolean first = true;
+
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class defaultNamespace_argsStandardSchemeFactory implements SchemeFactory {
+      public defaultNamespace_argsStandardScheme getScheme() {
+        return new defaultNamespace_argsStandardScheme();
+      }
+    }
+
+    private static class defaultNamespace_argsStandardScheme extends StandardScheme<defaultNamespace_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, defaultNamespace_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, defaultNamespace_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class defaultNamespace_argsTupleSchemeFactory implements SchemeFactory {
+      public defaultNamespace_argsTupleScheme getScheme() {
+        return new defaultNamespace_argsTupleScheme();
+      }
+    }
+
+    private static class defaultNamespace_argsTupleScheme extends TupleScheme<defaultNamespace_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, defaultNamespace_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, defaultNamespace_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+      }
+    }
+
+  }
+
+  public static class defaultNamespace_result implements org.apache.thrift.TBase<defaultNamespace_result, defaultNamespace_result._Fields>, java.io.Serializable, Cloneable, Comparable<defaultNamespace_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("defaultNamespace_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new defaultNamespace_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new defaultNamespace_resultTupleSchemeFactory());
+    }
+
+    public String success; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(defaultNamespace_result.class, metaDataMap);
+    }
+
+    public defaultNamespace_result() {
+    }
+
+    public defaultNamespace_result(
+      String success)
+    {
+      this();
+      this.success = success;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public defaultNamespace_result(defaultNamespace_result other) {
+      if (other.isSetSuccess()) {
+        this.success = other.success;
+      }
+    }
+
+    public defaultNamespace_result deepCopy() {
+      return new defaultNamespace_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+    }
+
+    public String getSuccess() {
+      return this.success;
+    }
+
+    public defaultNamespace_result setSuccess(String success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof defaultNamespace_result)
+        return this.equals((defaultNamespace_result)that);
+      return false;
+    }
+
+    public boolean equals(defaultNamespace_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(defaultNamespace_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("defaultNamespace_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class defaultNamespace_resultStandardSchemeFactory implements SchemeFactory {
+      public defaultNamespace_resultStandardScheme getScheme() {
+        return new defaultNamespace_resultStandardScheme();
+      }
+    }
+
+    private static class defaultNamespace_resultStandardScheme extends StandardScheme<defaultNamespace_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, defaultNamespace_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.success = iprot.readString();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, defaultNamespace_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeString(struct.success);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class defaultNamespace_resultTupleSchemeFactory implements SchemeFactory {
+      public defaultNamespace_resultTupleScheme getScheme() {
+        return new defaultNamespace_resultTupleScheme();
+      }
+    }
+
+    private static class defaultNamespace_resultTupleScheme extends TupleScheme<defaultNamespace_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, defaultNamespace_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetSuccess()) {
+          oprot.writeString(struct.success);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, defaultNamespace_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.success = iprot.readString();
+          struct.setSuccessIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class listNamespaces_args implements org.apache.thrift.TBase<listNamespaces_args, listNamespaces_args._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaces_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaces_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new listNamespaces_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new listNamespaces_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaces_args.class, metaDataMap);
+    }
+
+    public listNamespaces_args() {
+    }
+
+    public listNamespaces_args(
+      ByteBuffer login)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public listNamespaces_args(listNamespaces_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+    }
+
+    public listNamespaces_args deepCopy() {
+      return new listNamespaces_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public listNamespaces_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public listNamespaces_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof listNamespaces_args)
+        return this.equals((listNamespaces_args)that);
+      return false;
+    }
+
+    public boolean equals(listNamespaces_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(listNamespaces_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("listNamespaces_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class listNamespaces_argsStandardSchemeFactory implements SchemeFactory {
+      public listNamespaces_argsStandardScheme getScheme() {
+        return new listNamespaces_argsStandardScheme();
+      }
+    }
+
+    private static class listNamespaces_argsStandardScheme extends StandardScheme<listNamespaces_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, listNamespaces_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaces_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class listNamespaces_argsTupleSchemeFactory implements SchemeFactory {
+      public listNamespaces_argsTupleScheme getScheme() {
+        return new listNamespaces_argsTupleScheme();
+      }
+    }
+
+    private static class listNamespaces_argsTupleScheme extends TupleScheme<listNamespaces_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, listNamespaces_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaces_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class listNamespaces_result implements org.apache.thrift.TBase<listNamespaces_result, listNamespaces_result._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaces_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaces_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new listNamespaces_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new listNamespaces_resultTupleSchemeFactory());
+    }
+
+    public List<String> success; // required
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaces_result.class, metaDataMap);
+    }
+
+    public listNamespaces_result() {
+    }
+
+    public listNamespaces_result(
+      List<String> success,
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2)
+    {
+      this();
+      this.success = success;
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public listNamespaces_result(listNamespaces_result other) {
+      if (other.isSetSuccess()) {
+        List<String> __this__success = new ArrayList<String>(other.success);
+        this.success = __this__success;
+      }
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+    }
+
+    public listNamespaces_result deepCopy() {
+      return new listNamespaces_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.ouch1 = null;
+      this.ouch2 = null;
+    }
+
+    public int getSuccessSize() {
+      return (this.success == null) ? 0 : this.success.size();
+    }
+
+    public java.util.Iterator<String> getSuccessIterator() {
+      return (this.success == null) ? null : this.success.iterator();
+    }
+
+    public void addToSuccess(String elem) {
+      if (this.success == null) {
+        this.success = new ArrayList<String>();
+      }
+      this.success.add(elem);
+    }
+
+    public List<String> getSuccess() {
+      return this.success;
+    }
+
+    public listNamespaces_result setSuccess(List<String> success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public listNamespaces_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public listNamespaces_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((List<String>)value);
+        }
+        break;
+
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof listNamespaces_result)
+        return this.equals((listNamespaces_result)that);
+      return false;
+    }
+
+    public boolean equals(listNamespaces_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(listNamespaces_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("listNamespaces_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class listNamespaces_resultStandardSchemeFactory implements SchemeFactory {
+      public listNamespaces_resultStandardScheme getScheme() {
+        return new listNamespaces_resultStandardScheme();
+      }
+    }
+
+    private static class listNamespaces_resultStandardScheme extends StandardScheme<listNamespaces_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, listNamespaces_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
+                {
+                  org.apache.thrift.protocol.TList _list498 = iprot.readListBegin();
+                  struct.success = new ArrayList<String>(_list498.size);
+                  String _elem499;
+                  for (int _i500 = 0; _i500 < _list498.size; ++_i500)
+                  {
+                    _elem499 = iprot.readString();
+                    struct.success.add(_elem499);
+                  }
+                  iprot.readListEnd();
+                }
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaces_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          {
+            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
+            for (String _iter501 : struct.success)
+            {
+              oprot.writeString(_iter501);
+            }
+            oprot.writeListEnd();
+          }
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class listNamespaces_resultTupleSchemeFactory implements SchemeFactory {
+      public listNamespaces_resultTupleScheme getScheme() {
+        return new listNamespaces_resultTupleScheme();
+      }
+    }
+
+    private static class listNamespaces_resultTupleScheme extends TupleScheme<listNamespaces_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, listNamespaces_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch1()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetSuccess()) {
+          {
+            oprot.writeI32(struct.success.size());
+            for (String _iter502 : struct.success)
+            {
+              oprot.writeString(_iter502);
+            }
+          }
+        }
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaces_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          {
+            org.apache.thrift.protocol.TList _list503 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+            struct.success = new ArrayList<String>(_list503.size);
+            String _elem504;
+            for (int _i505 = 0; _i505 < _list503.size; ++_i505)
+            {
+              _elem504 = iprot.readString();
+              struct.success.add(_elem504);
+            }
+          }
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class namespaceExists_args implements org.apache.thrift.TBase<namespaceExists_args, namespaceExists_args._Fields>, java.io.Serializable, Cloneable, Comparable<namespaceExists_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("namespaceExists_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new namespaceExists_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new namespaceExists_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(namespaceExists_args.class, metaDataMap);
+    }
+
+    public namespaceExists_args() {
+    }
+
+    public namespaceExists_args(
+      ByteBuffer login,
+      String namespaceName)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public namespaceExists_args(namespaceExists_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+    }
+
+    public namespaceExists_args deepCopy() {
+      return new namespaceExists_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public namespaceExists_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public namespaceExists_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public namespaceExists_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof namespaceExists_args)
+        return this.equals((namespaceExists_args)that);
+      return false;
+    }
+
+    public boolean equals(namespaceExists_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(namespaceExists_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("namespaceExists_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class namespaceExists_argsStandardSchemeFactory implements SchemeFactory {
+      public namespaceExists_argsStandardScheme getScheme() {
+        return new namespaceExists_argsStandardScheme();
+      }
+    }
+
+    private static class namespaceExists_argsStandardScheme extends StandardScheme<namespaceExists_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, namespaceExists_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, namespaceExists_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class namespaceExists_argsTupleSchemeFactory implements SchemeFactory {
+      public namespaceExists_argsTupleScheme getScheme() {
+        return new namespaceExists_argsTupleScheme();
+      }
+    }
+
+    private static class namespaceExists_argsTupleScheme extends TupleScheme<namespaceExists_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, namespaceExists_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, namespaceExists_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class namespaceExists_result implements org.apache.thrift.TBase<namespaceExists_result, namespaceExists_result._Fields>, java.io.Serializable, Cloneable, Comparable<namespaceExists_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("namespaceExists_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new namespaceExists_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new namespaceExists_resultTupleSchemeFactory());
+    }
+
+    public boolean success; // required
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(namespaceExists_result.class, metaDataMap);
+    }
+
+    public namespaceExists_result() {
+    }
+
+    public namespaceExists_result(
+      boolean success,
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public namespaceExists_result(namespaceExists_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+    }
+
+    public namespaceExists_result deepCopy() {
+      return new namespaceExists_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = false;
+      this.ouch1 = null;
+      this.ouch2 = null;
+    }
+
+    public boolean isSuccess() {
+      return this.success;
+    }
+
+    public namespaceExists_result setSuccess(boolean success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public namespaceExists_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public namespaceExists_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Boolean)value);
+        }
+        break;
+
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return isSuccess();
+
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof namespaceExists_result)
+        return this.equals((namespaceExists_result)that);
+      return false;
+    }
+
+    public boolean equals(namespaceExists_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true;
+      boolean that_present_success = true;
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (this.success != that.success)
+          return false;
+      }
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(namespaceExists_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("namespaceExists_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class namespaceExists_resultStandardSchemeFactory implements SchemeFactory {
+      public namespaceExists_resultStandardScheme getScheme() {
+        return new namespaceExists_resultStandardScheme();
+      }
+    }
+
+    private static class namespaceExists_resultStandardScheme extends StandardScheme<namespaceExists_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, namespaceExists_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
+                struct.success = iprot.readBool();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, namespaceExists_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeBool(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class namespaceExists_resultTupleSchemeFactory implements SchemeFactory {
+      public namespaceExists_resultTupleScheme getScheme() {
+        return new namespaceExists_resultTupleScheme();
+      }
+    }
+
+    private static class namespaceExists_resultTupleScheme extends TupleScheme<namespaceExists_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, namespaceExists_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch1()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetSuccess()) {
+          oprot.writeBool(struct.success);
+        }
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, namespaceExists_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.success = iprot.readBool();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class createNamespace_args implements org.apache.thrift.TBase<createNamespace_args, createNamespace_args._Fields>, java.io.Serializable, Cloneable, Comparable<createNamespace_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createNamespace_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new createNamespace_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new createNamespace_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createNamespace_args.class, metaDataMap);
+    }
+
+    public createNamespace_args() {
+    }
+
+    public createNamespace_args(
+      ByteBuffer login,
+      String namespaceName)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public createNamespace_args(createNamespace_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+    }
+
+    public createNamespace_args deepCopy() {
+      return new createNamespace_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public createNamespace_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public createNamespace_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public createNamespace_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof createNamespace_args)
+        return this.equals((createNamespace_args)that);
+      return false;
+    }
+
+    public boolean equals(createNamespace_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(createNamespace_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("createNamespace_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class createNamespace_argsStandardSchemeFactory implements SchemeFactory {
+      public createNamespace_argsStandardScheme getScheme() {
+        return new createNamespace_argsStandardScheme();
+      }
+    }
+
+    private static class createNamespace_argsStandardScheme extends StandardScheme<createNamespace_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, createNamespace_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, createNamespace_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class createNamespace_argsTupleSchemeFactory implements SchemeFactory {
+      public createNamespace_argsTupleScheme getScheme() {
+        return new createNamespace_argsTupleScheme();
+      }
+    }
+
+    private static class createNamespace_argsTupleScheme extends TupleScheme<createNamespace_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, createNamespace_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, createNamespace_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class createNamespace_result implements org.apache.thrift.TBase<createNamespace_result, createNamespace_result._Fields>, java.io.Serializable, Cloneable, Comparable<createNamespace_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createNamespace_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new createNamespace_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new createNamespace_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceExistsException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createNamespace_result.class, metaDataMap);
+    }
+
+    public createNamespace_result() {
+    }
+
+    public createNamespace_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceExistsException ouch3)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public createNamespace_result(createNamespace_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceExistsException(other.ouch3);
+      }
+    }
+
+    public createNamespace_result deepCopy() {
+      return new createNamespace_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public createNamespace_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public createNamespace_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceExistsException getOuch3() {
+      return this.ouch3;
+    }
+
+    public createNamespace_result setOuch3(NamespaceExistsException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceExistsException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof createNamespace_result)
+        return this.equals((createNamespace_result)that);
+      return false;
+    }
+
+    public boolean equals(createNamespace_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(createNamespace_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("createNamespace_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class createNamespace_resultStandardSchemeFactory implements SchemeFactory {
+      public createNamespace_resultStandardScheme getScheme() {
+        return new createNamespace_resultStandardScheme();
+      }
+    }
+
+    private static class createNamespace_resultStandardScheme extends StandardScheme<createNamespace_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, createNamespace_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceExistsException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, createNamespace_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class createNamespace_resultTupleSchemeFactory implements SchemeFactory {
+      public createNamespace_resultTupleScheme getScheme() {
+        return new createNamespace_resultTupleScheme();
+      }
+    }
+
+    private static class createNamespace_resultTupleScheme extends TupleScheme<createNamespace_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, createNamespace_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, createNamespace_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch3 = new NamespaceExistsException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class deleteNamespace_args implements org.apache.thrift.TBase<deleteNamespace_args, deleteNamespace_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteNamespace_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteNamespace_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new deleteNamespace_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new deleteNamespace_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteNamespace_args.class, metaDataMap);
+    }
+
+    public deleteNamespace_args() {
+    }
+
+    public deleteNamespace_args(
+      ByteBuffer login,
+      String namespaceName)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public deleteNamespace_args(deleteNamespace_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+    }
+
+    public deleteNamespace_args deepCopy() {
+      return new deleteNamespace_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public deleteNamespace_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public deleteNamespace_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public deleteNamespace_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof deleteNamespace_args)
+        return this.equals((deleteNamespace_args)that);
+      return false;
+    }
+
+    public boolean equals(deleteNamespace_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(deleteNamespace_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("deleteNamespace_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class deleteNamespace_argsStandardSchemeFactory implements SchemeFactory {
+      public deleteNamespace_argsStandardScheme getScheme() {
+        return new deleteNamespace_argsStandardScheme();
+      }
+    }
+
+    private static class deleteNamespace_argsStandardScheme extends StandardScheme<deleteNamespace_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteNamespace_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteNamespace_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class deleteNamespace_argsTupleSchemeFactory implements SchemeFactory {
+      public deleteNamespace_argsTupleScheme getScheme() {
+        return new deleteNamespace_argsTupleScheme();
+      }
+    }
+
+    private static class deleteNamespace_argsTupleScheme extends TupleScheme<deleteNamespace_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, deleteNamespace_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, deleteNamespace_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class deleteNamespace_result implements org.apache.thrift.TBase<deleteNamespace_result, deleteNamespace_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteNamespace_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteNamespace_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+    private static final org.apache.thrift.protocol.TField OUCH4_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch4", org.apache.thrift.protocol.TType.STRUCT, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new deleteNamespace_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new deleteNamespace_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+    public NamespaceNotEmptyException ouch4; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3"),
+      OUCH4((short)4, "ouch4");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          case 4: // OUCH4
+            return OUCH4;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH4, new org.apache.thrift.meta_data.FieldMetaData("ouch4", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteNamespace_result.class, metaDataMap);
+    }
+
+    public deleteNamespace_result() {
+    }
+
+    public deleteNamespace_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3,
+      NamespaceNotEmptyException ouch4)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+      this.ouch4 = ouch4;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public deleteNamespace_result(deleteNamespace_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+      if (other.isSetOuch4()) {
+        this.ouch4 = new NamespaceNotEmptyException(other.ouch4);
+      }
+    }
+
+    public deleteNamespace_result deepCopy() {
+      return new deleteNamespace_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+      this.ouch4 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public deleteNamespace_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public deleteNamespace_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public deleteNamespace_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public NamespaceNotEmptyException getOuch4() {
+      return this.ouch4;
+    }
+
+    public deleteNamespace_result setOuch4(NamespaceNotEmptyException ouch4) {
+      this.ouch4 = ouch4;
+      return this;
+    }
+
+    public void unsetOuch4() {
+      this.ouch4 = null;
+    }
+
+    /** Returns true if field ouch4 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch4() {
+      return this.ouch4 != null;
+    }
+
+    public void setOuch4IsSet(boolean value) {
+      if (!value) {
+        this.ouch4 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      case OUCH4:
+        if (value == null) {
+          unsetOuch4();
+        } else {
+          setOuch4((NamespaceNotEmptyException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      case OUCH4:
+        return getOuch4();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      case OUCH4:
+        return isSetOuch4();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof deleteNamespace_result)
+        return this.equals((deleteNamespace_result)that);
+      return false;
+    }
+
+    public boolean equals(deleteNamespace_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      boolean this_present_ouch4 = true && this.isSetOuch4();
+      boolean that_present_ouch4 = true && that.isSetOuch4();
+      if (this_present_ouch4 || that_present_ouch4) {
+        if (!(this_present_ouch4 && that_present_ouch4))
+          return false;
+        if (!this.ouch4.equals(that.ouch4))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      boolean present_ouch4 = true && (isSetOuch4());
+      list.add(present_ouch4);
+      if (present_ouch4)
+        list.add(ouch4);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(deleteNamespace_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch4()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch4, other.ouch4);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("deleteNamespace_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch4:");
+      if (this.ouch4 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch4);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class deleteNamespace_resultStandardSchemeFactory implements SchemeFactory {
+      public deleteNamespace_resultStandardScheme getScheme() {
+        return new deleteNamespace_resultStandardScheme();
+      }
+    }
+
+    private static class deleteNamespace_resultStandardScheme extends StandardScheme<deleteNamespace_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteNamespace_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // OUCH4
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch4 = new NamespaceNotEmptyException();
+                struct.ouch4.read(iprot);
+                struct.setOuch4IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteNamespace_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch4 != null) {
+          oprot.writeFieldBegin(OUCH4_FIELD_DESC);
+          struct.ouch4.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class deleteNamespace_resultTupleSchemeFactory implements SchemeFactory {
+      public deleteNamespace_resultTupleScheme getScheme() {
+        return new deleteNamespace_resultTupleScheme();
+      }
+    }
+
+    private static class deleteNamespace_resultTupleScheme extends TupleScheme<deleteNamespace_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, deleteNamespace_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(2);
+        }
+        if (struct.isSetOuch4()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+        if (struct.isSetOuch4()) {
+          struct.ouch4.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, deleteNamespace_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.ouch4 = new NamespaceNotEmptyException();
+          struct.ouch4.read(iprot);
+          struct.setOuch4IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class renameNamespace_args implements org.apache.thrift.TBase<renameNamespace_args, renameNamespace_args._Fields>, java.io.Serializable, Cloneable, Comparable<renameNamespace_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("renameNamespace_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField OLD_NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("oldNamespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField NEW_NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("newNamespaceName", org.apache.thrift.protocol.TType.STRING, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new renameNamespace_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new renameNamespace_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String oldNamespaceName; // required
+    public String newNamespaceName; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      OLD_NAMESPACE_NAME((short)2, "oldNamespaceName"),
+      NEW_NAMESPACE_NAME((short)3, "newNamespaceName");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // OLD_NAMESPACE_NAME
+            return OLD_NAMESPACE_NAME;
+          case 3: // NEW_NAMESPACE_NAME
+            return NEW_NAMESPACE_NAME;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.OLD_NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("oldNamespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.NEW_NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("newNamespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(renameNamespace_args.class, metaDataMap);
+    }
+
+    public renameNamespace_args() {
+    }
+
+    public renameNamespace_args(
+      ByteBuffer login,
+      String oldNamespaceName,
+      String newNamespaceName)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.oldNamespaceName = oldNamespaceName;
+      this.newNamespaceName = newNamespaceName;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public renameNamespace_args(renameNamespace_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetOldNamespaceName()) {
+        this.oldNamespaceName = other.oldNamespaceName;
+      }
+      if (other.isSetNewNamespaceName()) {
+        this.newNamespaceName = other.newNamespaceName;
+      }
+    }
+
+    public renameNamespace_args deepCopy() {
+      return new renameNamespace_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.oldNamespaceName = null;
+      this.newNamespaceName = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public renameNamespace_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public renameNamespace_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getOldNamespaceName() {
+      return this.oldNamespaceName;
+    }
+
+    public renameNamespace_args setOldNamespaceName(String oldNamespaceName) {
+      this.oldNamespaceName = oldNamespaceName;
+      return this;
+    }
+
+    public void unsetOldNamespaceName() {
+      this.oldNamespaceName = null;
+    }
+
+    /** Returns true if field oldNamespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetOldNamespaceName() {
+      return this.oldNamespaceName != null;
+    }
+
+    public void setOldNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.oldNamespaceName = null;
+      }
+    }
+
+    public String getNewNamespaceName() {
+      return this.newNamespaceName;
+    }
+
+    public renameNamespace_args setNewNamespaceName(String newNamespaceName) {
+      this.newNamespaceName = newNamespaceName;
+      return this;
+    }
+
+    public void unsetNewNamespaceName() {
+      this.newNamespaceName = null;
+    }
+
+    /** Returns true if field newNamespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNewNamespaceName() {
+      return this.newNamespaceName != null;
+    }
+
+    public void setNewNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.newNamespaceName = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case OLD_NAMESPACE_NAME:
+        if (value == null) {
+          unsetOldNamespaceName();
+        } else {
+          setOldNamespaceName((String)value);
+        }
+        break;
+
+      case NEW_NAMESPACE_NAME:
+        if (value == null) {
+          unsetNewNamespaceName();
+        } else {
+          setNewNamespaceName((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case OLD_NAMESPACE_NAME:
+        return getOldNamespaceName();
+
+      case NEW_NAMESPACE_NAME:
+        return getNewNamespaceName();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case OLD_NAMESPACE_NAME:
+        return isSetOldNamespaceName();
+      case NEW_NAMESPACE_NAME:
+        return isSetNewNamespaceName();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof renameNamespace_args)
+        return this.equals((renameNamespace_args)that);
+      return false;
+    }
+
+    public boolean equals(renameNamespace_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_oldNamespaceName = true && this.isSetOldNamespaceName();
+      boolean that_present_oldNamespaceName = true && that.isSetOldNamespaceName();
+      if (this_present_oldNamespaceName || that_present_oldNamespaceName) {
+        if (!(this_present_oldNamespaceName && that_present_oldNamespaceName))
+          return false;
+        if (!this.oldNamespaceName.equals(that.oldNamespaceName))
+          return false;
+      }
+
+      boolean this_present_newNamespaceName = true && this.isSetNewNamespaceName();
+      boolean that_present_newNamespaceName = true && that.isSetNewNamespaceName();
+      if (this_present_newNamespaceName || that_present_newNamespaceName) {
+        if (!(this_present_newNamespaceName && that_present_newNamespaceName))
+          return false;
+        if (!this.newNamespaceName.equals(that.newNamespaceName))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_oldNamespaceName = true && (isSetOldNamespaceName());
+      list.add(present_oldNamespaceName);
+      if (present_oldNamespaceName)
+        list.add(oldNamespaceName);
+
+      boolean present_newNamespaceName = true && (isSetNewNamespaceName());
+      list.add(present_newNamespaceName);
+      if (present_newNamespaceName)
+        list.add(newNamespaceName);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(renameNamespace_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOldNamespaceName()).compareTo(other.isSetOldNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOldNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.oldNamespaceName, other.oldNamespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNewNamespaceName()).compareTo(other.isSetNewNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNewNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.newNamespaceName, other.newNamespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("renameNamespace_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("oldNamespaceName:");
+      if (this.oldNamespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.oldNamespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("newNamespaceName:");
+      if (this.newNamespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.newNamespaceName);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class renameNamespace_argsStandardSchemeFactory implements SchemeFactory {
+      public renameNamespace_argsStandardScheme getScheme() {
+        return new renameNamespace_argsStandardScheme();
+      }
+    }
+
+    private static class renameNamespace_argsStandardScheme extends StandardScheme<renameNamespace_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, renameNamespace_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OLD_NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.oldNamespaceName = iprot.readString();
+                struct.setOldNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // NEW_NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.newNamespaceName = iprot.readString();
+                struct.setNewNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, renameNamespace_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.oldNamespaceName != null) {
+          oprot.writeFieldBegin(OLD_NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.oldNamespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.newNamespaceName != null) {
+          oprot.writeFieldBegin(NEW_NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.newNamespaceName);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class renameNamespace_argsTupleSchemeFactory implements SchemeFactory {
+      public renameNamespace_argsTupleScheme getScheme() {
+        return new renameNamespace_argsTupleScheme();
+      }
+    }
+
+    private static class renameNamespace_argsTupleScheme extends TupleScheme<renameNamespace_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, renameNamespace_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOldNamespaceName()) {
+          optionals.set(1);
+        }
+        if (struct.isSetNewNamespaceName()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetOldNamespaceName()) {
+          oprot.writeString(struct.oldNamespaceName);
+        }
+        if (struct.isSetNewNamespaceName()) {
+          oprot.writeString(struct.newNamespaceName);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, renameNamespace_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.oldNamespaceName = iprot.readString();
+          struct.setOldNamespaceNameIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.newNamespaceName = iprot.readString();
+          struct.setNewNamespaceNameIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class renameNamespace_result implements org.apache.thrift.TBase<renameNamespace_result, renameNamespace_result._Fields>, java.io.Serializable, Cloneable, Comparable<renameNamespace_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("renameNamespace_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+    private static final org.apache.thrift.protocol.TField OUCH4_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch4", org.apache.thrift.protocol.TType.STRUCT, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new renameNamespace_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new renameNamespace_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+    public NamespaceExistsException ouch4; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3"),
+      OUCH4((short)4, "ouch4");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          case 4: // OUCH4
+            return OUCH4;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH4, new org.apache.thrift.meta_data.FieldMetaData("ouch4", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(renameNamespace_result.class, metaDataMap);
+    }
+
+    public renameNamespace_result() {
+    }
+
+    public renameNamespace_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3,
+      NamespaceExistsException ouch4)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+      this.ouch4 = ouch4;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public renameNamespace_result(renameNamespace_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+      if (other.isSetOuch4()) {
+        this.ouch4 = new NamespaceExistsException(other.ouch4);
+      }
+    }
+
+    public renameNamespace_result deepCopy() {
+      return new renameNamespace_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+      this.ouch4 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public renameNamespace_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public renameNamespace_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public renameNamespace_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public NamespaceExistsException getOuch4() {
+      return this.ouch4;
+    }
+
+    public renameNamespace_result setOuch4(NamespaceExistsException ouch4) {
+      this.ouch4 = ouch4;
+      return this;
+    }
+
+    public void unsetOuch4() {
+      this.ouch4 = null;
+    }
+
+    /** Returns true if field ouch4 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch4() {
+      return this.ouch4 != null;
+    }
+
+    public void setOuch4IsSet(boolean value) {
+      if (!value) {
+        this.ouch4 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      case OUCH4:
+        if (value == null) {
+          unsetOuch4();
+        } else {
+          setOuch4((NamespaceExistsException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      case OUCH4:
+        return getOuch4();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      case OUCH4:
+        return isSetOuch4();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof renameNamespace_result)
+        return this.equals((renameNamespace_result)that);
+      return false;
+    }
+
+    public boolean equals(renameNamespace_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      boolean this_present_ouch4 = true && this.isSetOuch4();
+      boolean that_present_ouch4 = true && that.isSetOuch4();
+      if (this_present_ouch4 || that_present_ouch4) {
+        if (!(this_present_ouch4 && that_present_ouch4))
+          return false;
+        if (!this.ouch4.equals(that.ouch4))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      boolean present_ouch4 = true && (isSetOuch4());
+      list.add(present_ouch4);
+      if (present_ouch4)
+        list.add(ouch4);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(renameNamespace_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch4()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch4, other.ouch4);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("renameNamespace_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch4:");
+      if (this.ouch4 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch4);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class renameNamespace_resultStandardSchemeFactory implements SchemeFactory {
+      public renameNamespace_resultStandardScheme getScheme() {
+        return new renameNamespace_resultStandardScheme();
+      }
+    }
+
+    private static class renameNamespace_resultStandardScheme extends StandardScheme<renameNamespace_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, renameNamespace_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // OUCH4
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch4 = new NamespaceExistsException();
+                struct.ouch4.read(iprot);
+                struct.setOuch4IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, renameNamespace_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch4 != null) {
+          oprot.writeFieldBegin(OUCH4_FIELD_DESC);
+          struct.ouch4.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class renameNamespace_resultTupleSchemeFactory implements SchemeFactory {
+      public renameNamespace_resultTupleScheme getScheme() {
+        return new renameNamespace_resultTupleScheme();
+      }
+    }
+
+    private static class renameNamespace_resultTupleScheme extends TupleScheme<renameNamespace_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, renameNamespace_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(2);
+        }
+        if (struct.isSetOuch4()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+        if (struct.isSetOuch4()) {
+          struct.ouch4.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, renameNamespace_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.ouch4 = new NamespaceExistsException();
+          struct.ouch4.read(iprot);
+          struct.setOuch4IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class setNamespaceProperty_args implements org.apache.thrift.TBase<setNamespaceProperty_args, setNamespaceProperty_args._Fields>, java.io.Serializable, Cloneable, Comparable<setNamespaceProperty_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("setNamespaceProperty_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField PROPERTY_FIELD_DESC = new org.apache.thrift.protocol.TField("property", org.apache.thrift.protocol.TType.STRING, (short)3);
+    private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRING, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new setNamespaceProperty_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new setNamespaceProperty_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+    public String property; // required
+    public String value; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName"),
+      PROPERTY((short)3, "property"),
+      VALUE((short)4, "value");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 3: // PROPERTY
+            return PROPERTY;
+          case 4: // VALUE
+            return VALUE;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.PROPERTY, new org.apache.thrift.meta_data.FieldMetaData("property", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setNamespaceProperty_args.class, metaDataMap);
+    }
+
+    public setNamespaceProperty_args() {
+    }
+
+    public setNamespaceProperty_args(
+      ByteBuffer login,
+      String namespaceName,
+      String property,
+      String value)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+      this.property = property;
+      this.value = value;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public setNamespaceProperty_args(setNamespaceProperty_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetProperty()) {
+        this.property = other.property;
+      }
+      if (other.isSetValue()) {
+        this.value = other.value;
+      }
+    }
+
+    public setNamespaceProperty_args deepCopy() {
+      return new setNamespaceProperty_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+      this.property = null;
+      this.value = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public setNamespaceProperty_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public setNamespaceProperty_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public setNamespaceProperty_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public String getProperty() {
+      return this.property;
+    }
+
+    public setNamespaceProperty_args setProperty(String property) {
+      this.property = property;
+      return this;
+    }
+
+    public void unsetProperty() {
+      this.property = null;
+    }
+
+    /** Returns true if field property is set (has been assigned a value) and false otherwise */
+    public boolean isSetProperty() {
+      return this.property != null;
+    }
+
+    public void setPropertyIsSet(boolean value) {
+      if (!value) {
+        this.property = null;
+      }
+    }
+
+    public String getValue() {
+      return this.value;
+    }
+
+    public setNamespaceProperty_args setValue(String value) {
+      this.value = value;
+      return this;
+    }
+
+    public void unsetValue() {
+      this.value = null;
+    }
+
+    /** Returns true if field value is set (has been assigned a value) and false otherwise */
+    public boolean isSetValue() {
+      return this.value != null;
+    }
+
+    public void setValueIsSet(boolean value) {
+      if (!value) {
+        this.value = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case PROPERTY:
+        if (value == null) {
+          unsetProperty();
+        } else {
+          setProperty((String)value);
+        }
+        break;
+
+      case VALUE:
+        if (value == null) {
+          unsetValue();
+        } else {
+          setValue((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case PROPERTY:
+        return getProperty();
+
+      case VALUE:
+        return getValue();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case PROPERTY:
+        return isSetProperty();
+      case VALUE:
+        return isSetValue();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof setNamespaceProperty_args)
+        return this.equals((setNamespaceProperty_args)that);
+      return false;
+    }
+
+    public boolean equals(setNamespaceProperty_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_property = true && this.isSetProperty();
+      boolean that_present_property = true && that.isSetProperty();
+      if (this_present_property || that_present_property) {
+        if (!(this_present_property && that_present_property))
+          return false;
+        if (!this.property.equals(that.property))
+          return false;
+      }
+
+      boolean this_present_value = true && this.isSetValue();
+      boolean that_present_value = true && that.isSetValue();
+      if (this_present_value || that_present_value) {
+        if (!(this_present_value && that_present_value))
+          return false;
+        if (!this.value.equals(that.value))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_property = true && (isSetProperty());
+      list.add(present_property);
+      if (present_property)
+        list.add(property);
+
+      boolean present_value = true && (isSetValue());
+      list.add(present_value);
+      if (present_value)
+        list.add(value);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(setNamespaceProperty_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetProperty()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.property, other.property);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetValue()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, other.value);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("setNamespaceProperty_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("property:");
+      if (this.property == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.property);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("value:");
+      if (this.value == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.value);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class setNamespaceProperty_argsStandardSchemeFactory implements SchemeFactory {
+      public setNamespaceProperty_argsStandardScheme getScheme() {
+        return new setNamespaceProperty_argsStandardScheme();
+      }
+    }
+
+    private static class setNamespaceProperty_argsStandardScheme extends StandardScheme<setNamespaceProperty_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, setNamespaceProperty_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // PROPERTY
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.property = iprot.readString();
+                struct.setPropertyIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // VALUE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.value = iprot.readString();
+                struct.setValueIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, setNamespaceProperty_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.property != null) {
+          oprot.writeFieldBegin(PROPERTY_FIELD_DESC);
+          oprot.writeString(struct.property);
+          oprot.writeFieldEnd();
+        }
+        if (struct.value != null) {
+          oprot.writeFieldBegin(VALUE_FIELD_DESC);
+          oprot.writeString(struct.value);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class setNamespaceProperty_argsTupleSchemeFactory implements SchemeFactory {
+      public setNamespaceProperty_argsTupleScheme getScheme() {
+        return new setNamespaceProperty_argsTupleScheme();
+      }
+    }
+
+    private static class setNamespaceProperty_argsTupleScheme extends TupleScheme<setNamespaceProperty_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, setNamespaceProperty_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        if (struct.isSetProperty()) {
+          optionals.set(2);
+        }
+        if (struct.isSetValue()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetProperty()) {
+          oprot.writeString(struct.property);
+        }
+        if (struct.isSetValue()) {
+          oprot.writeString(struct.value);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, setNamespaceProperty_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.property = iprot.readString();
+          struct.setPropertyIsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.value = iprot.readString();
+          struct.setValueIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class setNamespaceProperty_result implements org.apache.thrift.TBase<setNamespaceProperty_result, setNamespaceProperty_result._Fields>, java.io.Serializable, Cloneable, Comparable<setNamespaceProperty_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("setNamespaceProperty_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new setNamespaceProperty_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new setNamespaceProperty_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setNamespaceProperty_result.class, metaDataMap);
+    }
+
+    public setNamespaceProperty_result() {
+    }
+
+    public setNamespaceProperty_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public setNamespaceProperty_result(setNamespaceProperty_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public setNamespaceProperty_result deepCopy() {
+      return new setNamespaceProperty_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public setNamespaceProperty_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public setNamespaceProperty_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public setNamespaceProperty_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof setNamespaceProperty_result)
+        return this.equals((setNamespaceProperty_result)that);
+      return false;
+    }
+
+    public boolean equals(setNamespaceProperty_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(setNamespaceProperty_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("setNamespaceProperty_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class setNamespaceProperty_resultStandardSchemeFactory implements SchemeFactory {
+      public setNamespaceProperty_resultStandardScheme getScheme() {
+        return new setNamespaceProperty_resultStandardScheme();
+      }
+    }
+
+    private static class setNamespaceProperty_resultStandardScheme extends StandardScheme<setNamespaceProperty_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, setNamespaceProperty_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, setNamespaceProperty_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class setNamespaceProperty_resultTupleSchemeFactory implements SchemeFactory {
+      public setNamespaceProperty_resultTupleScheme getScheme() {
+        return new setNamespaceProperty_resultTupleScheme();
+      }
+    }
+
+    private static class setNamespaceProperty_resultTupleScheme extends TupleScheme<setNamespaceProperty_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, setNamespaceProperty_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, setNamespaceProperty_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class removeNamespaceProperty_args implements org.apache.thrift.TBase<removeNamespaceProperty_args, removeNamespaceProperty_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceProperty_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceProperty_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField PROPERTY_FIELD_DESC = new org.apache.thrift.protocol.TField("property", org.apache.thrift.protocol.TType.STRING, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new removeNamespaceProperty_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new removeNamespaceProperty_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+    public String property; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName"),
+      PROPERTY((short)3, "property");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 3: // PROPERTY
+            return PROPERTY;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.PROPERTY, new org.apache.thrift.meta_data.FieldMetaData("property", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceProperty_args.class, metaDataMap);
+    }
+
+    public removeNamespaceProperty_args() {
+    }
+
+    public removeNamespaceProperty_args(
+      ByteBuffer login,
+      String namespaceName,
+      String property)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+      this.property = property;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public removeNamespaceProperty_args(removeNamespaceProperty_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetProperty()) {
+        this.property = other.property;
+      }
+    }
+
+    public removeNamespaceProperty_args deepCopy() {
+      return new removeNamespaceProperty_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+      this.property = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public removeNamespaceProperty_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public removeNamespaceProperty_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public removeNamespaceProperty_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public String getProperty() {
+      return this.property;
+    }
+
+    public removeNamespaceProperty_args setProperty(String property) {
+      this.property = property;
+      return this;
+    }
+
+    public void unsetProperty() {
+      this.property = null;
+    }
+
+    /** Returns true if field property is set (has been assigned a value) and false otherwise */
+    public boolean isSetProperty() {
+      return this.property != null;
+    }
+
+    public void setPropertyIsSet(boolean value) {
+      if (!value) {
+        this.property = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case PROPERTY:
+        if (value == null) {
+          unsetProperty();
+        } else {
+          setProperty((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case PROPERTY:
+        return getProperty();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case PROPERTY:
+        return isSetProperty();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof removeNamespaceProperty_args)
+        return this.equals((removeNamespaceProperty_args)that);
+      return false;
+    }
+
+    public boolean equals(removeNamespaceProperty_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_property = true && this.isSetProperty();
+      boolean that_present_property = true && that.isSetProperty();
+      if (this_present_property || that_present_property) {
+        if (!(this_present_property && that_present_property))
+          return false;
+        if (!this.property.equals(that.property))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_property = true && (isSetProperty());
+      list.add(present_property);
+      if (present_property)
+        list.add(property);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(removeNamespaceProperty_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetProperty()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.property, other.property);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("removeNamespaceProperty_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("property:");
+      if (this.property == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.property);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class removeNamespaceProperty_argsStandardSchemeFactory implements SchemeFactory {
+      public removeNamespaceProperty_argsStandardScheme getScheme() {
+        return new removeNamespaceProperty_argsStandardScheme();
+      }
+    }
+
+    private static class removeNamespaceProperty_argsStandardScheme extends StandardScheme<removeNamespaceProperty_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, removeNamespaceProperty_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // PROPERTY
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.property = iprot.readString();
+                struct.setPropertyIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceProperty_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.property != null) {
+          oprot.writeFieldBegin(PROPERTY_FIELD_DESC);
+          oprot.writeString(struct.property);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class removeNamespaceProperty_argsTupleSchemeFactory implements SchemeFactory {
+      public removeNamespaceProperty_argsTupleScheme getScheme() {
+        return new removeNamespaceProperty_argsTupleScheme();
+      }
+    }
+
+    private static class removeNamespaceProperty_argsTupleScheme extends TupleScheme<removeNamespaceProperty_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, removeNamespaceProperty_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        if (struct.isSetProperty()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetProperty()) {
+          oprot.writeString(struct.property);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceProperty_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.property = iprot.readString();
+          struct.setPropertyIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class removeNamespaceProperty_result implements org.apache.thrift.TBase<removeNamespaceProperty_result, removeNamespaceProperty_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceProperty_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceProperty_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new removeNamespaceProperty_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new removeNamespaceProperty_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceProperty_result.class, metaDataMap);
+    }
+
+    public removeNamespaceProperty_result() {
+    }
+
+    public removeNamespaceProperty_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public removeNamespaceProperty_result(removeNamespaceProperty_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public removeNamespaceProperty_result deepCopy() {
+      return new removeNamespaceProperty_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public removeNamespaceProperty_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public removeNamespaceProperty_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public removeNamespaceProperty_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof removeNamespaceProperty_result)
+        return this.equals((removeNamespaceProperty_result)that);
+      return false;
+    }
+
+    public boolean equals(removeNamespaceProperty_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(removeNamespaceProperty_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("removeNamespaceProperty_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class removeNamespaceProperty_resultStandardSchemeFactory implements SchemeFactory {
+      public removeNamespaceProperty_resultStandardScheme getScheme() {
+        return new removeNamespaceProperty_resultStandardScheme();
+      }
+    }
+
+    private static class removeNamespaceProperty_resultStandardScheme extends StandardScheme<removeNamespaceProperty_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, removeNamespaceProperty_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceProperty_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class removeNamespaceProperty_resultTupleSchemeFactory implements SchemeFactory {
+      public removeNamespaceProperty_resultTupleScheme getScheme() {
+        return new removeNamespaceProperty_resultTupleScheme();
+      }
+    }
+
+    private static class removeNamespaceProperty_resultTupleScheme extends TupleScheme<removeNamespaceProperty_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, removeNamespaceProperty_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceProperty_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class getNamespaceProperties_args implements org.apache.thrift.TBase<getNamespaceProperties_args, getNamespaceProperties_args._Fields>, java.io.Serializable, Cloneable, Comparable<getNamespaceProperties_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getNamespaceProperties_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new getNamespaceProperties_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new getNamespaceProperties_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getNamespaceProperties_args.class, metaDataMap);
+    }
+
+    public getNamespaceProperties_args() {
+    }
+
+    public getNamespaceProperties_args(
+      ByteBuffer login,
+      String namespaceName)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public getNamespaceProperties_args(getNamespaceProperties_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+    }
+
+    public getNamespaceProperties_args deepCopy() {
+      return new getNamespaceProperties_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public getNamespaceProperties_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public getNamespaceProperties_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public getNamespaceProperties_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof getNamespaceProperties_args)
+        return this.equals((getNamespaceProperties_args)that);
+      return false;
+    }
+
+    public boolean equals(getNamespaceProperties_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(getNamespaceProperties_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("getNamespaceProperties_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class getNamespaceProperties_argsStandardSchemeFactory implements SchemeFactory {
+      public getNamespaceProperties_argsStandardScheme getScheme() {
+        return new getNamespaceProperties_argsStandardScheme();
+      }
+    }
+
+    private static class getNamespaceProperties_argsStandardScheme extends StandardScheme<getNamespaceProperties_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, getNamespaceProperties_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, getNamespaceProperties_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class getNamespaceProperties_argsTupleSchemeFactory implements SchemeFactory {
+      public getNamespaceProperties_argsTupleScheme getScheme() {
+        return new getNamespaceProperties_argsTupleScheme();
+      }
+    }
+
+    private static class getNamespaceProperties_argsTupleScheme extends TupleScheme<getNamespaceProperties_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, getNamespaceProperties_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, getNamespaceProperties_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class getNamespaceProperties_result implements org.apache.thrift.TBase<getNamespaceProperties_result, getNamespaceProperties_result._Fields>, java.io.Serializable, Cloneable, Comparable<getNamespaceProperties_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getNamespaceProperties_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new getNamespaceProperties_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new getNamespaceProperties_resultTupleSchemeFactory());
+    }
+
+    public Map<String,String> success; // required
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
+              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
+              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getNamespaceProperties_result.class, metaDataMap);
+    }
+
+    public getNamespaceProperties_result() {
+    }
+
+    public getNamespaceProperties_result(
+      Map<String,String> success,
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.success = success;
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public getNamespaceProperties_result(getNamespaceProperties_result other) {
+      if (other.isSetSuccess()) {
+        Map<String,String> __this__success = new HashMap<String,String>(other.success);
+        this.success = __this__success;
+      }
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public getNamespaceProperties_result deepCopy() {
+      return new getNamespaceProperties_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public int getSuccessSize() {
+      return (this.success == null) ? 0 : this.success.size();
+    }
+
+    public void putToSuccess(String key, String val) {
+      if (this.success == null) {
+        this.success = new HashMap<String,String>();
+      }
+      this.success.put(key, val);
+    }
+
+    public Map<String,String> getSuccess() {
+      return this.success;
+    }
+
+    public getNamespaceProperties_result setSuccess(Map<String,String> success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public getNamespaceProperties_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public getNamespaceProperties_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public getNamespaceProperties_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Map<String,String>)value);
+        }
+        break;
+
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof getNamespaceProperties_result)
+        return this.equals((getNamespaceProperties_result)that);
+      return false;
+    }
+
+    public boolean equals(getNamespaceProperties_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(getNamespaceProperties_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("getNamespaceProperties_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class getNamespaceProperties_resultStandardSchemeFactory implements SchemeFactory {
+      public getNamespaceProperties_resultStandardScheme getScheme() {
+        return new getNamespaceProperties_resultStandardScheme();
+      }
+    }
+
+    private static class getNamespaceProperties_resultStandardScheme extends StandardScheme<getNamespaceProperties_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, getNamespaceProperties_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
+                {
+                  org.apache.thrift.protocol.TMap _map506 = iprot.readMapBegin();
+                  struct.success = new HashMap<String,String>(2*_map506.size);
+                  String _key507;
+                  String _val508;
+                  for (int _i509 = 0; _i509 < _map506.size; ++_i509)
+                  {
+                    _key507 = iprot.readString();
+                    _val508 = iprot.readString();
+                    struct.success.put(_key507, _val508);
+                  }
+                  iprot.readMapEnd();
+                }
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, getNamespaceProperties_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          {
+            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
+            for (Map.Entry<String, String> _iter510 : struct.success.entrySet())
+            {
+              oprot.writeString(_iter510.getKey());
+              oprot.writeString(_iter510.getValue());
+            }
+            oprot.writeMapEnd();
+          }
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class getNamespaceProperties_resultTupleSchemeFactory implements SchemeFactory {
+      public getNamespaceProperties_resultTupleScheme getScheme() {
+        return new getNamespaceProperties_resultTupleScheme();
+      }
+    }
+
+    private static class getNamespaceProperties_resultTupleScheme extends TupleScheme<getNamespaceProperties_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, getNamespaceProperties_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch1()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(2);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetSuccess()) {
+          {
+            oprot.writeI32(struct.success.size());
+            for (Map.Entry<String, String> _iter511 : struct.success.entrySet())
+            {
+              oprot.writeString(_iter511.getKey());
+              oprot.writeString(_iter511.getValue());
+            }
+          }
+        }
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, getNamespaceProperties_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          {
+            org.apache.thrift.protocol.TMap _map512 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+            struct.success = new HashMap<String,String>(2*_map512.size);
+            String _key513;
+            String _val514;
+            for (int _i515 = 0; _i515 < _map512.size; ++_i515)
+            {
+              _key513 = iprot.readString();
+              _val514 = iprot.readString();
+              struct.success.put(_key513, _val514);
+            }
+          }
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class namespaceIdMap_args implements org.apache.thrift.TBase<namespaceIdMap_args, namespaceIdMap_args._Fields>, java.io.Serializable, Cloneable, Comparable<namespaceIdMap_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("namespaceIdMap_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new namespaceIdMap_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new namespaceIdMap_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(namespaceIdMap_args.class, metaDataMap);
+    }
+
+    public namespaceIdMap_args() {
+    }
+
+    public namespaceIdMap_args(
+      ByteBuffer login)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public namespaceIdMap_args(namespaceIdMap_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+    }
+
+    public namespaceIdMap_args deepCopy() {
+      return new namespaceIdMap_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public namespaceIdMap_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public namespaceIdMap_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof namespaceIdMap_args)
+        return this.equals((namespaceIdMap_args)that);
+      return false;
+    }
+
+    public boolean equals(namespaceIdMap_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(namespaceIdMap_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("namespaceIdMap_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class namespaceIdMap_argsStandardSchemeFactory implements SchemeFactory {
+      public namespaceIdMap_argsStandardScheme getScheme() {
+        return new namespaceIdMap_argsStandardScheme();
+      }
+    }
+
+    private static class namespaceIdMap_argsStandardScheme extends StandardScheme<namespaceIdMap_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, namespaceIdMap_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, namespaceIdMap_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class namespaceIdMap_argsTupleSchemeFactory implements SchemeFactory {
+      public namespaceIdMap_argsTupleScheme getScheme() {
+        return new namespaceIdMap_argsTupleScheme();
+      }
+    }
+
+    private static class namespaceIdMap_argsTupleScheme extends TupleScheme<namespaceIdMap_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, namespaceIdMap_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, namespaceIdMap_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class namespaceIdMap_result implements org.apache.thrift.TBase<namespaceIdMap_result, namespaceIdMap_result._Fields>, java.io.Serializable, Cloneable, Comparable<namespaceIdMap_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("namespaceIdMap_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new namespaceIdMap_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new namespaceIdMap_resultTupleSchemeFactory());
+    }
+
+    public Map<String,String> success; // required
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
+              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
+              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(namespaceIdMap_result.class, metaDataMap);
+    }
+
+    public namespaceIdMap_result() {
+    }
+
+    public namespaceIdMap_result(
+      Map<String,String> success,
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2)
+    {
+      this();
+      this.success = success;
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public namespaceIdMap_result(namespaceIdMap_result other) {
+      if (other.isSetSuccess()) {
+        Map<String,String> __this__success = new HashMap<String,String>(other.success);
+        this.success = __this__success;
+      }
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+    }
+
+    public namespaceIdMap_result deepCopy() {
+      return new namespaceIdMap_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.ouch1 = null;
+      this.ouch2 = null;
+    }
+
+    public int getSuccessSize() {
+      return (this.success == null) ? 0 : this.success.size();
+    }
+
+    public void putToSuccess(String key, String val) {
+      if (this.success == null) {
+        this.success = new HashMap<String,String>();
+      }
+      this.success.put(key, val);
+    }
+
+    public Map<String,String> getSuccess() {
+      return this.success;
+    }
+
+    public namespaceIdMap_result setSuccess(Map<String,String> success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public namespaceIdMap_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public namespaceIdMap_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Map<String,String>)value);
+        }
+        break;
+
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof namespaceIdMap_result)
+        return this.equals((namespaceIdMap_result)that);
+      return false;
+    }
+
+    public boolean equals(namespaceIdMap_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(namespaceIdMap_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("namespaceIdMap_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class namespaceIdMap_resultStandardSchemeFactory implements SchemeFactory {
+      public namespaceIdMap_resultStandardScheme getScheme() {
+        return new namespaceIdMap_resultStandardScheme();
+      }
+    }
+
+    private static class namespaceIdMap_resultStandardScheme extends StandardScheme<namespaceIdMap_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, namespaceIdMap_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
+                {
+                  org.apache.thrift.protocol.TMap _map516 = iprot.readMapBegin();
+                  struct.success = new HashMap<String,String>(2*_map516.size);
+                  String _key517;
+                  String _val518;
+                  for (int _i519 = 0; _i519 < _map516.size; ++_i519)
+                  {
+                    _key517 = iprot.readString();
+                    _val518 = iprot.readString();
+                    struct.success.put(_key517, _val518);
+                  }
+                  iprot.readMapEnd();
+                }
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, namespaceIdMap_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          {
+            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.success.size()));
+            for (Map.Entry<String, String> _iter520 : struct.success.entrySet())
+            {
+              oprot.writeString(_iter520.getKey());
+              oprot.writeString(_iter520.getValue());
+            }
+            oprot.writeMapEnd();
+          }
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class namespaceIdMap_resultTupleSchemeFactory implements SchemeFactory {
+      public namespaceIdMap_resultTupleScheme getScheme() {
+        return new namespaceIdMap_resultTupleScheme();
+      }
+    }
+
+    private static class namespaceIdMap_resultTupleScheme extends TupleScheme<namespaceIdMap_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, namespaceIdMap_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch1()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetSuccess()) {
+          {
+            oprot.writeI32(struct.success.size());
+            for (Map.Entry<String, String> _iter521 : struct.success.entrySet())
+            {
+              oprot.writeString(_iter521.getKey());
+              oprot.writeString(_iter521.getValue());
+            }
+          }
+        }
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, namespaceIdMap_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          {
+            org.apache.thrift.protocol.TMap _map522 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+            struct.success = new HashMap<String,String>(2*_map522.size);
+            String _key523;
+            String _val524;
+            for (int _i525 = 0; _i525 < _map522.size; ++_i525)
+            {
+              _key523 = iprot.readString();
+              _val524 = iprot.readString();
+              struct.success.put(_key523, _val524);
+            }
+          }
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class attachNamespaceIterator_args implements org.apache.thrift.TBase<attachNamespaceIterator_args, attachNamespaceIterator_args._Fields>, java.io.Serializable, Cloneable, Comparable<attachNamespaceIterator_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("attachNamespaceIterator_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField SETTING_FIELD_DESC = new org.apache.thrift.protocol.TField("setting", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+    private static final org.apache.thrift.protocol.TField SCOPES_FIELD_DESC = new org.apache.thrift.protocol.TField("scopes", org.apache.thrift.protocol.TType.SET, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new attachNamespaceIterator_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new attachNamespaceIterator_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+    public IteratorSetting setting; // required
+    public Set<IteratorScope> scopes; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName"),
+      SETTING((short)3, "setting"),
+      SCOPES((short)4, "scopes");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 3: // SETTING
+            return SETTING;
+          case 4: // SCOPES
+            return SCOPES;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.SETTING, new org.apache.thrift.meta_data.FieldMetaData("setting", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class)));
+      tmpMap.put(_Fields.SCOPES, new org.apache.thrift.meta_data.FieldMetaData("scopes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
+              new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class))));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(attachNamespaceIterator_args.class, metaDataMap);
+    }
+
+    public attachNamespaceIterator_args() {
+    }
+
+    public attachNamespaceIterator_args(
+      ByteBuffer login,
+      String namespaceName,
+      IteratorSetting setting,
+      Set<IteratorScope> scopes)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+      this.setting = setting;
+      this.scopes = scopes;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public attachNamespaceIterator_args(attachNamespaceIterator_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetSetting()) {
+        this.setting = new IteratorSetting(other.setting);
+      }
+      if (other.isSetScopes()) {
+        Set<IteratorScope> __this__scopes = new HashSet<IteratorScope>(other.scopes.size());
+        for (IteratorScope other_element : other.scopes) {
+          __this__scopes.add(other_element);
+        }
+        this.scopes = __this__scopes;
+      }
+    }
+
+    public attachNamespaceIterator_args deepCopy() {
+      return new attachNamespaceIterator_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+      this.setting = null;
+      this.scopes = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public attachNamespaceIterator_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public attachNamespaceIterator_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public attachNamespaceIterator_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public IteratorSetting getSetting() {
+      return this.setting;
+    }
+
+    public attachNamespaceIterator_args setSetting(IteratorSetting setting) {
+      this.setting = setting;
+      return this;
+    }
+
+    public void unsetSetting() {
+      this.setting = null;
+    }
+
+    /** Returns true if field setting is set (has been assigned a value) and false otherwise */
+    public boolean isSetSetting() {
+      return this.setting != null;
+    }
+
+    public void setSettingIsSet(boolean value) {
+      if (!value) {
+        this.setting = null;
+      }
+    }
+
+    public int getScopesSize() {
+      return (this.scopes == null) ? 0 : this.scopes.size();
+    }
+
+    public java.util.Iterator<IteratorScope> getScopesIterator() {
+      return (this.scopes == null) ? null : this.scopes.iterator();
+    }
+
+    public void addToScopes(IteratorScope elem) {
+      if (this.scopes == null) {
+        this.scopes = new HashSet<IteratorScope>();
+      }
+      this.scopes.add(elem);
+    }
+
+    public Set<IteratorScope> getScopes() {
+      return this.scopes;
+    }
+
+    public attachNamespaceIterator_args setScopes(Set<IteratorScope> scopes) {
+      this.scopes = scopes;
+      return this;
+    }
+
+    public void unsetScopes() {
+      this.scopes = null;
+    }
+
+    /** Returns true if field scopes is set (has been assigned a value) and false otherwise */
+    public boolean isSetScopes() {
+      return this.scopes != null;
+    }
+
+    public void setScopesIsSet(boolean value) {
+      if (!value) {
+        this.scopes = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case SETTING:
+        if (value == null) {
+          unsetSetting();
+        } else {
+          setSetting((IteratorSetting)value);
+        }
+        break;
+
+      case SCOPES:
+        if (value == null) {
+          unsetScopes();
+        } else {
+          setScopes((Set<IteratorScope>)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case SETTING:
+        return getSetting();
+
+      case SCOPES:
+        return getScopes();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case SETTING:
+        return isSetSetting();
+      case SCOPES:
+        return isSetScopes();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof attachNamespaceIterator_args)
+        return this.equals((attachNamespaceIterator_args)that);
+      return false;
+    }
+
+    public boolean equals(attachNamespaceIterator_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_setting = true && this.isSetSetting();
+      boolean that_present_setting = true && that.isSetSetting();
+      if (this_present_setting || that_present_setting) {
+        if (!(this_present_setting && that_present_setting))
+          return false;
+        if (!this.setting.equals(that.setting))
+          return false;
+      }
+
+      boolean this_present_scopes = true && this.isSetScopes();
+      boolean that_present_scopes = true && that.isSetScopes();
+      if (this_present_scopes || that_present_scopes) {
+        if (!(this_present_scopes && that_present_scopes))
+          return false;
+        if (!this.scopes.equals(that.scopes))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_setting = true && (isSetSetting());
+      list.add(present_setting);
+      if (present_setting)
+        list.add(setting);
+
+      boolean present_scopes = true && (isSetScopes());
+      list.add(present_scopes);
+      if (present_scopes)
+        list.add(scopes);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(attachNamespaceIterator_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSetting()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.setting, other.setting);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetScopes()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scopes, other.scopes);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("attachNamespaceIterator_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("setting:");
+      if (this.setting == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.setting);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("scopes:");
+      if (this.scopes == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.scopes);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (setting != null) {
+        setting.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class attachNamespaceIterator_argsStandardSchemeFactory implements SchemeFactory {
+      public attachNamespaceIterator_argsStandardScheme getScheme() {
+        return new attachNamespaceIterator_argsStandardScheme();
+      }
+    }
+
+    private static class attachNamespaceIterator_argsStandardScheme extends StandardScheme<attachNamespaceIterator_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, attachNamespaceIterator_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // SETTING
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.setting = new IteratorSetting();
+                struct.setting.read(iprot);
+                struct.setSettingIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // SCOPES
+              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
+                {
+                  org.apache.thrift.protocol.TSet _set526 = iprot.readSetBegin();
+                  struct.scopes = new HashSet<IteratorScope>(2*_set526.size);
+                  IteratorScope _elem527;
+                  for (int _i528 = 0; _i528 < _set526.size; ++_i528)
+                  {
+                    _elem527 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                    struct.scopes.add(_elem527);
+                  }
+                  iprot.readSetEnd();
+                }
+                struct.setScopesIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, attachNamespaceIterator_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.setting != null) {
+          oprot.writeFieldBegin(SETTING_FIELD_DESC);
+          struct.setting.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.scopes != null) {
+          oprot.writeFieldBegin(SCOPES_FIELD_DESC);
+          {
+            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.scopes.size()));
+            for (IteratorScope _iter529 : struct.scopes)
+            {
+              oprot.writeI32(_iter529.getValue());
+            }
+            oprot.writeSetEnd();
+          }
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class attachNamespaceIterator_argsTupleSchemeFactory implements SchemeFactory {
+      public attachNamespaceIterator_argsTupleScheme getScheme() {
+        return new attachNamespaceIterator_argsTupleScheme();
+      }
+    }
+
+    private static class attachNamespaceIterator_argsTupleScheme extends TupleScheme<attachNamespaceIterator_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, attachNamespaceIterator_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        if (struct.isSetSetting()) {
+          optionals.set(2);
+        }
+        if (struct.isSetScopes()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetSetting()) {
+          struct.setting.write(oprot);
+        }
+        if (struct.isSetScopes()) {
+          {
+            oprot.writeI32(struct.scopes.size());
+            for (IteratorScope _iter530 : struct.scopes)
+            {
+              oprot.writeI32(_iter530.getValue());
+            }
+          }
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, attachNamespaceIterator_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.setting = new IteratorSetting();
+          struct.setting.read(iprot);
+          struct.setSettingIsSet(true);
+        }
+        if (incoming.get(3)) {
+          {
+            org.apache.thrift.protocol.TSet _set531 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
+            struct.scopes = new HashSet<IteratorScope>(2*_set531.size);
+            IteratorScope _elem532;
+            for (int _i533 = 0; _i533 < _set531.size; ++_i533)
+            {
+              _elem532 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+              struct.scopes.add(_elem532);
+            }
+          }
+          struct.setScopesIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class attachNamespaceIterator_result implements org.apache.thrift.TBase<attachNamespaceIterator_result, attachNamespaceIterator_result._Fields>, java.io.Serializable, Cloneable, Comparable<attachNamespaceIterator_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("attachNamespaceIterator_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new attachNamespaceIterator_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new attachNamespaceIterator_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(attachNamespaceIterator_result.class, metaDataMap);
+    }
+
+    public attachNamespaceIterator_result() {
+    }
+
+    public attachNamespaceIterator_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public attachNamespaceIterator_result(attachNamespaceIterator_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public attachNamespaceIterator_result deepCopy() {
+      return new attachNamespaceIterator_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public attachNamespaceIterator_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public attachNamespaceIterator_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public attachNamespaceIterator_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof attachNamespaceIterator_result)
+        return this.equals((attachNamespaceIterator_result)that);
+      return false;
+    }
+
+    public boolean equals(attachNamespaceIterator_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(attachNamespaceIterator_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("attachNamespaceIterator_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class attachNamespaceIterator_resultStandardSchemeFactory implements SchemeFactory {
+      public attachNamespaceIterator_resultStandardScheme getScheme() {
+        return new attachNamespaceIterator_resultStandardScheme();
+      }
+    }
+
+    private static class attachNamespaceIterator_resultStandardScheme extends StandardScheme<attachNamespaceIterator_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, attachNamespaceIterator_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, attachNamespaceIterator_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class attachNamespaceIterator_resultTupleSchemeFactory implements SchemeFactory {
+      public attachNamespaceIterator_resultTupleScheme getScheme() {
+        return new attachNamespaceIterator_resultTupleScheme();
+      }
+    }
+
+    private static class attachNamespaceIterator_resultTupleScheme extends TupleScheme<attachNamespaceIterator_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, attachNamespaceIterator_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, attachNamespaceIterator_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class removeNamespaceIterator_args implements org.apache.thrift.TBase<removeNamespaceIterator_args, removeNamespaceIterator_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceIterator_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceIterator_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)3);
+    private static final org.apache.thrift.protocol.TField SCOPES_FIELD_DESC = new org.apache.thrift.protocol.TField("scopes", org.apache.thrift.protocol.TType.SET, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new removeNamespaceIterator_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new removeNamespaceIterator_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+    public String name; // required
+    public Set<IteratorScope> scopes; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName"),
+      NAME((short)3, "name"),
+      SCOPES((short)4, "scopes");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 3: // NAME
+            return NAME;
+          case 4: // SCOPES
+            return SCOPES;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.SCOPES, new org.apache.thrift.meta_data.FieldMetaData("scopes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
+              new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class))));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceIterator_args.class, metaDataMap);
+    }
+
+    public removeNamespaceIterator_args() {
+    }
+
+    public removeNamespaceIterator_args(
+      ByteBuffer login,
+      String namespaceName,
+      String name,
+      Set<IteratorScope> scopes)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+      this.name = name;
+      this.scopes = scopes;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public removeNamespaceIterator_args(removeNamespaceIterator_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetName()) {
+        this.name = other.name;
+      }
+      if (other.isSetScopes()) {
+        Set<IteratorScope> __this__scopes = new HashSet<IteratorScope>(other.scopes.size());
+        for (IteratorScope other_element : other.scopes) {
+          __this__scopes.add(other_element);
+        }
+        this.scopes = __this__scopes;
+      }
+    }
+
+    public removeNamespaceIterator_args deepCopy() {
+      return new removeNamespaceIterator_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+      this.name = null;
+      this.scopes = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public removeNamespaceIterator_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public removeNamespaceIterator_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public removeNamespaceIterator_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public String getName() {
+      return this.name;
+    }
+
+    public removeNamespaceIterator_args setName(String name) {
+      this.name = name;
+      return this;
+    }
+
+    public void unsetName() {
+      this.name = null;
+    }
+
+    /** Returns true if field name is set (has been assigned a value) and false otherwise */
+    public boolean isSetName() {
+      return this.name != null;
+    }
+
+    public void setNameIsSet(boolean value) {
+      if (!value) {
+        this.name = null;
+      }
+    }
+
+    public int getScopesSize() {
+      return (this.scopes == null) ? 0 : this.scopes.size();
+    }
+
+    public java.util.Iterator<IteratorScope> getScopesIterator() {
+      return (this.scopes == null) ? null : this.scopes.iterator();
+    }
+
+    public void addToScopes(IteratorScope elem) {
+      if (this.scopes == null) {
+        this.scopes = new HashSet<IteratorScope>();
+      }
+      this.scopes.add(elem);
+    }
+
+    public Set<IteratorScope> getScopes() {
+      return this.scopes;
+    }
+
+    public removeNamespaceIterator_args setScopes(Set<IteratorScope> scopes) {
+      this.scopes = scopes;
+      return this;
+    }
+
+    public void unsetScopes() {
+      this.scopes = null;
+    }
+
+    /** Returns true if field scopes is set (has been assigned a value) and false otherwise */
+    public boolean isSetScopes() {
+      return this.scopes != null;
+    }
+
+    public void setScopesIsSet(boolean value) {
+      if (!value) {
+        this.scopes = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case NAME:
+        if (value == null) {
+          unsetName();
+        } else {
+          setName((String)value);
+        }
+        break;
+
+      case SCOPES:
+        if (value == null) {
+          unsetScopes();
+        } else {
+          setScopes((Set<IteratorScope>)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case NAME:
+        return getName();
+
+      case SCOPES:
+        return getScopes();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case NAME:
+        return isSetName();
+      case SCOPES:
+        return isSetScopes();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof removeNamespaceIterator_args)
+        return this.equals((removeNamespaceIterator_args)that);
+      return false;
+    }
+
+    public boolean equals(removeNamespaceIterator_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_name = true && this.isSetName();
+      boolean that_present_name = true && that.isSetName();
+      if (this_present_name || that_present_name) {
+        if (!(this_present_name && that_present_name))
+          return false;
+        if (!this.name.equals(that.name))
+          return false;
+      }
+
+      boolean this_present_scopes = true && this.isSetScopes();
+      boolean that_present_scopes = true && that.isSetScopes();
+      if (this_present_scopes || that_present_scopes) {
+        if (!(this_present_scopes && that_present_scopes))
+          return false;
+        if (!this.scopes.equals(that.scopes))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_name = true && (isSetName());
+      list.add(present_name);
+      if (present_name)
+        list.add(name);
+
+      boolean present_scopes = true && (isSetScopes());
+      list.add(present_scopes);
+      if (present_scopes)
+        list.add(scopes);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(removeNamespaceIterator_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetScopes()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scopes, other.scopes);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("removeNamespaceIterator_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("name:");
+      if (this.name == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.name);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("scopes:");
+      if (this.scopes == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.scopes);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class removeNamespaceIterator_argsStandardSchemeFactory implements SchemeFactory {
+      public removeNamespaceIterator_argsStandardScheme getScheme() {
+        return new removeNamespaceIterator_argsStandardScheme();
+      }
+    }
+
+    private static class removeNamespaceIterator_argsStandardScheme extends StandardScheme<removeNamespaceIterator_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, removeNamespaceIterator_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.name = iprot.readString();
+                struct.setNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // SCOPES
+              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
+                {
+                  org.apache.thrift.protocol.TSet _set534 = iprot.readSetBegin();
+                  struct.scopes = new HashSet<IteratorScope>(2*_set534.size);
+                  IteratorScope _elem535;
+                  for (int _i536 = 0; _i536 < _set534.size; ++_i536)
+                  {
+                    _elem535 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                    struct.scopes.add(_elem535);
+                  }
+                  iprot.readSetEnd();
+                }
+                struct.setScopesIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceIterator_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.name != null) {
+          oprot.writeFieldBegin(NAME_FIELD_DESC);
+          oprot.writeString(struct.name);
+          oprot.writeFieldEnd();
+        }
+        if (struct.scopes != null) {
+          oprot.writeFieldBegin(SCOPES_FIELD_DESC);
+          {
+            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.scopes.size()));
+            for (IteratorScope _iter537 : struct.scopes)
+            {
+              oprot.writeI32(_iter537.getValue());
+            }
+            oprot.writeSetEnd();
+          }
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class removeNamespaceIterator_argsTupleSchemeFactory implements SchemeFactory {
+      public removeNamespaceIterator_argsTupleScheme getScheme() {
+        return new removeNamespaceIterator_argsTupleScheme();
+      }
+    }
+
+    private static class removeNamespaceIterator_argsTupleScheme extends TupleScheme<removeNamespaceIterator_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, removeNamespaceIterator_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        if (struct.isSetName()) {
+          optionals.set(2);
+        }
+        if (struct.isSetScopes()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetName()) {
+          oprot.writeString(struct.name);
+        }
+        if (struct.isSetScopes()) {
+          {
+            oprot.writeI32(struct.scopes.size());
+            for (IteratorScope _iter538 : struct.scopes)
+            {
+              oprot.writeI32(_iter538.getValue());
+            }
+          }
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceIterator_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.name = iprot.readString();
+          struct.setNameIsSet(true);
+        }
+        if (incoming.get(3)) {
+          {
+            org.apache.thrift.protocol.TSet _set539 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
+            struct.scopes = new HashSet<IteratorScope>(2*_set539.size);
+            IteratorScope _elem540;
+            for (int _i541 = 0; _i541 < _set539.size; ++_i541)
+            {
+              _elem540 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+              struct.scopes.add(_elem540);
+            }
+          }
+          struct.setScopesIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class removeNamespaceIterator_result implements org.apache.thrift.TBase<removeNamespaceIterator_result, removeNamespaceIterator_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceIterator_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceIterator_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new removeNamespaceIterator_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new removeNamespaceIterator_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceIterator_result.class, metaDataMap);
+    }
+
+    public removeNamespaceIterator_result() {
+    }
+
+    public removeNamespaceIterator_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public removeNamespaceIterator_result(removeNamespaceIterator_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public removeNamespaceIterator_result deepCopy() {
+      return new removeNamespaceIterator_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public removeNamespaceIterator_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public removeNamespaceIterator_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public removeNamespaceIterator_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof removeNamespaceIterator_result)
+        return this.equals((removeNamespaceIterator_result)that);
+      return false;
+    }
+
+    public boolean equals(removeNamespaceIterator_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(removeNamespaceIterator_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("removeNamespaceIterator_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class removeNamespaceIterator_resultStandardSchemeFactory implements SchemeFactory {
+      public removeNamespaceIterator_resultStandardScheme getScheme() {
+        return new removeNamespaceIterator_resultStandardScheme();
+      }
+    }
+
+    private static class removeNamespaceIterator_resultStandardScheme extends StandardScheme<removeNamespaceIterator_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, removeNamespaceIterator_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceIterator_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class removeNamespaceIterator_resultTupleSchemeFactory implements SchemeFactory {
+      public removeNamespaceIterator_resultTupleScheme getScheme() {
+        return new removeNamespaceIterator_resultTupleScheme();
+      }
+    }
+
+    private static class removeNamespaceIterator_resultTupleScheme extends TupleScheme<removeNamespaceIterator_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, removeNamespaceIterator_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceIterator_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class getNamespaceIteratorSetting_args implements org.apache.thrift.TBase<getNamespaceIteratorSetting_args, getNamespaceIteratorSetting_args._Fields>, java.io.Serializable, Cloneable, Comparable<getNamespaceIteratorSetting_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getNamespaceIteratorSetting_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)3);
+    private static final org.apache.thrift.protocol.TField SCOPE_FIELD_DESC = new org.apache.thrift.protocol.TField("scope", org.apache.thrift.protocol.TType.I32, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new getNamespaceIteratorSetting_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new getNamespaceIteratorSetting_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+    public String name; // required
+    /**
+     * 
+     * @see IteratorScope
+     */
+    public IteratorScope scope; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName"),
+      NAME((short)3, "name"),
+      /**
+       * 
+       * @see IteratorScope
+       */
+      SCOPE((short)4, "scope");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 3: // NAME
+            return NAME;
+          case 4: // SCOPE
+            return SCOPE;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.SCOPE, new org.apache.thrift.meta_data.FieldMetaData("scope", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getNamespaceIteratorSetting_args.class, metaDataMap);
+    }
+
+    public getNamespaceIteratorSetting_args() {
+    }
+
+    public getNamespaceIteratorSetting_args(
+      ByteBuffer login,
+      String namespaceName,
+      String name,
+      IteratorScope scope)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+      this.name = name;
+      this.scope = scope;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public getNamespaceIteratorSetting_args(getNamespaceIteratorSetting_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetName()) {
+        this.name = other.name;
+      }
+      if (other.isSetScope()) {
+        this.scope = other.scope;
+      }
+    }
+
+    public getNamespaceIteratorSetting_args deepCopy() {
+      return new getNamespaceIteratorSetting_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+      this.name = null;
+      this.scope = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public getNamespaceIteratorSetting_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public getNamespaceIteratorSetting_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public getNamespaceIteratorSetting_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public String getName() {
+      return this.name;
+    }
+
+    public getNamespaceIteratorSetting_args setName(String name) {
+      this.name = name;
+      return this;
+    }
+
+    public void unsetName() {
+      this.name = null;
+    }
+
+    /** Returns true if field name is set (has been assigned a value) and false otherwise */
+    public boolean isSetName() {
+      return this.name != null;
+    }
+
+    public void setNameIsSet(boolean value) {
+      if (!value) {
+        this.name = null;
+      }
+    }
+
+    /**
+     * 
+     * @see IteratorScope
+     */
+    public IteratorScope getScope() {
+      return this.scope;
+    }
+
+    /**
+     * 
+     * @see IteratorScope
+     */
+    public getNamespaceIteratorSetting_args setScope(IteratorScope scope) {
+      this.scope = scope;
+      return this;
+    }
+
+    public void unsetScope() {
+      this.scope = null;
+    }
+
+    /** Returns true if field scope is set (has been assigned a value) and false otherwise */
+    public boolean isSetScope() {
+      return this.scope != null;
+    }
+
+    public void setScopeIsSet(boolean value) {
+      if (!value) {
+        this.scope = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case NAME:
+        if (value == null) {
+          unsetName();
+        } else {
+          setName((String)value);
+        }
+        break;
+
+      case SCOPE:
+        if (value == null) {
+          unsetScope();
+        } else {
+          setScope((IteratorScope)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case NAME:
+        return getName();
+
+      case SCOPE:
+        return getScope();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case NAME:
+        return isSetName();
+      case SCOPE:
+        return isSetScope();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof getNamespaceIteratorSetting_args)
+        return this.equals((getNamespaceIteratorSetting_args)that);
+      return false;
+    }
+
+    public boolean equals(getNamespaceIteratorSetting_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_name = true && this.isSetName();
+      boolean that_present_name = true && that.isSetName();
+      if (this_present_name || that_present_name) {
+        if (!(this_present_name && that_present_name))
+          return false;
+        if (!this.name.equals(that.name))
+          return false;
+      }
+
+      boolean this_present_scope = true && this.isSetScope();
+      boolean that_present_scope = true && that.isSetScope();
+      if (this_present_scope || that_present_scope) {
+        if (!(this_present_scope && that_present_scope))
+          return false;
+        if (!this.scope.equals(that.scope))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_name = true && (isSetName());
+      list.add(present_name);
+      if (present_name)
+        list.add(name);
+
+      boolean present_scope = true && (isSetScope());
+      list.add(present_scope);
+      if (present_scope)
+        list.add(scope.getValue());
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(getNamespaceIteratorSetting_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetScope()).compareTo(other.isSetScope());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetScope()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scope, other.scope);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("getNamespaceIteratorSetting_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("name:");
+      if (this.name == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.name);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("scope:");
+      if (this.scope == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.scope);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class getNamespaceIteratorSetting_argsStandardSchemeFactory implements SchemeFactory {
+      public getNamespaceIteratorSetting_argsStandardScheme getScheme() {
+        return new getNamespaceIteratorSetting_argsStandardScheme();
+      }
+    }
+
+    private static class getNamespaceIteratorSetting_argsStandardScheme extends StandardScheme<getNamespaceIteratorSetting_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, getNamespaceIteratorSetting_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.name = iprot.readString();
+                struct.setNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // SCOPE
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.scope = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                struct.setScopeIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, getNamespaceIteratorSetting_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.name != null) {
+          oprot.writeFieldBegin(NAME_FIELD_DESC);
+          oprot.writeString(struct.name);
+          oprot.writeFieldEnd();
+        }
+        if (struct.scope != null) {
+          oprot.writeFieldBegin(SCOPE_FIELD_DESC);
+          oprot.writeI32(struct.scope.getValue());
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class getNamespaceIteratorSetting_argsTupleSchemeFactory implements SchemeFactory {
+      public getNamespaceIteratorSetting_argsTupleScheme getScheme() {
+        return new getNamespaceIteratorSetting_argsTupleScheme();
+      }
+    }
+
+    private static class getNamespaceIteratorSetting_argsTupleScheme extends TupleScheme<getNamespaceIteratorSetting_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, getNamespaceIteratorSetting_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        if (struct.isSetName()) {
+          optionals.set(2);
+        }
+        if (struct.isSetScope()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetName()) {
+          oprot.writeString(struct.name);
+        }
+        if (struct.isSetScope()) {
+          oprot.writeI32(struct.scope.getValue());
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, getNamespaceIteratorSetting_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.name = iprot.readString();
+          struct.setNameIsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.scope = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+          struct.setScopeIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class getNamespaceIteratorSetting_result implements org.apache.thrift.TBase<getNamespaceIteratorSetting_result, getNamespaceIteratorSetting_result._Fields>, java.io.Serializable, Cloneable, Comparable<getNamespaceIteratorSetting_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getNamespaceIteratorSetting_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new getNamespaceIteratorSetting_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new getNamespaceIteratorSetting_resultTupleSchemeFactory());
+    }
+
+    public IteratorSetting success; // required
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class)));
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getNamespaceIteratorSetting_result.class, metaDataMap);
+    }
+
+    public getNamespaceIteratorSetting_result() {
+    }
+
+    public getNamespaceIteratorSetting_result(
+      IteratorSetting success,
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.success = success;
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public getNamespaceIteratorSetting_result(getNamespaceIteratorSetting_result other) {
+      if (other.isSetSuccess()) {
+        this.success = new IteratorSetting(other.success);
+      }
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public getNamespaceIteratorSetting_result deepCopy() {
+      return new getNamespaceIteratorSetting_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public IteratorSetting getSuccess() {
+      return this.success;
+    }
+
+    public getNamespaceIteratorSetting_result setSuccess(IteratorSetting success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public getNamespaceIteratorSetting_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public getNamespaceIteratorSetting_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public getNamespaceIteratorSetting_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((IteratorSetting)value);
+        }
+        break;
+
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof getNamespaceIteratorSetting_result)
+        return this.equals((getNamespaceIteratorSetting_result)that);
+      return false;
+    }
+
+    public boolean equals(getNamespaceIteratorSetting_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(getNamespaceIteratorSetting_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("getNamespaceIteratorSetting_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (success != null) {
+        success.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class getNamespaceIteratorSetting_resultStandardSchemeFactory implements SchemeFactory {
+      public getNamespaceIteratorSetting_resultStandardScheme getScheme() {
+        return new getNamespaceIteratorSetting_resultStandardScheme();
+      }
+    }
+
+    private static class getNamespaceIteratorSetting_resultStandardScheme extends StandardScheme<getNamespaceIteratorSetting_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, getNamespaceIteratorSetting_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.success = new IteratorSetting();
+                struct.success.read(iprot);
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, getNamespaceIteratorSetting_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          struct.success.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class getNamespaceIteratorSetting_resultTupleSchemeFactory implements SchemeFactory {
+      public getNamespaceIteratorSetting_resultTupleScheme getScheme() {
+        return new getNamespaceIteratorSetting_resultTupleScheme();
+      }
+    }
+
+    private static class getNamespaceIteratorSetting_resultTupleScheme extends TupleScheme<getNamespaceIteratorSetting_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, getNamespaceIteratorSetting_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch1()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(2);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetSuccess()) {
+          struct.success.write(oprot);
+        }
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, getNamespaceIteratorSetting_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.success = new IteratorSetting();
+          struct.success.read(iprot);
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class listNamespaceIterators_args implements org.apache.thrift.TBase<listNamespaceIterators_args, listNamespaceIterators_args._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaceIterators_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaceIterators_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new listNamespaceIterators_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new listNamespaceIterators_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaceIterators_args.class, metaDataMap);
+    }
+
+    public listNamespaceIterators_args() {
+    }
+
+    public listNamespaceIterators_args(
+      ByteBuffer login,
+      String namespaceName)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public listNamespaceIterators_args(listNamespaceIterators_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+    }
+
+    public listNamespaceIterators_args deepCopy() {
+      return new listNamespaceIterators_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public listNamespaceIterators_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public listNamespaceIterators_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public listNamespaceIterators_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof listNamespaceIterators_args)
+        return this.equals((listNamespaceIterators_args)that);
+      return false;
+    }
+
+    public boolean equals(listNamespaceIterators_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(listNamespaceIterators_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("listNamespaceIterators_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class listNamespaceIterators_argsStandardSchemeFactory implements SchemeFactory {
+      public listNamespaceIterators_argsStandardScheme getScheme() {
+        return new listNamespaceIterators_argsStandardScheme();
+      }
+    }
+
+    private static class listNamespaceIterators_argsStandardScheme extends StandardScheme<listNamespaceIterators_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, listNamespaceIterators_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaceIterators_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class listNamespaceIterators_argsTupleSchemeFactory implements SchemeFactory {
+      public listNamespaceIterators_argsTupleScheme getScheme() {
+        return new listNamespaceIterators_argsTupleScheme();
+      }
+    }
+
+    private static class listNamespaceIterators_argsTupleScheme extends TupleScheme<listNamespaceIterators_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, listNamespaceIterators_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaceIterators_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class listNamespaceIterators_result implements org.apache.thrift.TBase<listNamespaceIterators_result, listNamespaceIterators_result._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaceIterators_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaceIterators_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new listNamespaceIterators_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new listNamespaceIterators_resultTupleSchemeFactory());
+    }
+
+    public Map<String,Set<IteratorScope>> success; // required
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
+              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
+              new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
+                  new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class)))));
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaceIterators_result.class, metaDataMap);
+    }
+
+    public listNamespaceIterators_result() {
+    }
+
+    public listNamespaceIterators_result(
+      Map<String,Set<IteratorScope>> success,
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.success = success;
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public listNamespaceIterators_result(listNamespaceIterators_result other) {
+      if (other.isSetSuccess()) {
+        Map<String,Set<IteratorScope>> __this__success = new HashMap<String,Set<IteratorScope>>(other.success.size());
+        for (Map.Entry<String, Set<IteratorScope>> other_element : other.success.entrySet()) {
+
+          String other_element_key = other_element.getKey();
+          Set<IteratorScope> other_element_value = other_element.getValue();
+
+          String __this__success_copy_key = other_element_key;
+
+          Set<IteratorScope> __this__success_copy_value = new HashSet<IteratorScope>(other_element_value.size());
+          for (IteratorScope other_element_value_element : other_element_value) {
+            __this__success_copy_value.add(other_element_value_element);
+          }
+
+          __this__success.put(__this__success_copy_key, __this__success_copy_value);
+        }
+        this.success = __this__success;
+      }
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public listNamespaceIterators_result deepCopy() {
+      return new listNamespaceIterators_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public int getSuccessSize() {
+      return (this.success == null) ? 0 : this.success.size();
+    }
+
+    public void putToSuccess(String key, Set<IteratorScope> val) {
+      if (this.success == null) {
+        this.success = new HashMap<String,Set<IteratorScope>>();
+      }
+      this.success.put(key, val);
+    }
+
+    public Map<String,Set<IteratorScope>> getSuccess() {
+      return this.success;
+    }
+
+    public listNamespaceIterators_result setSuccess(Map<String,Set<IteratorScope>> success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public listNamespaceIterators_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public listNamespaceIterators_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public listNamespaceIterators_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Map<String,Set<IteratorScope>>)value);
+        }
+        break;
+
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof listNamespaceIterators_result)
+        return this.equals((listNamespaceIterators_result)that);
+      return false;
+    }
+
+    public boolean equals(listNamespaceIterators_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(listNamespaceIterators_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("listNamespaceIterators_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class listNamespaceIterators_resultStandardSchemeFactory implements SchemeFactory {
+      public listNamespaceIterators_resultStandardScheme getScheme() {
+        return new listNamespaceIterators_resultStandardScheme();
+      }
+    }
+
+    private static class listNamespaceIterators_resultStandardScheme extends StandardScheme<listNamespaceIterators_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, listNamespaceIterators_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
+                {
+                  org.apache.thrift.protocol.TMap _map542 = iprot.readMapBegin();
+                  struct.success = new HashMap<String,Set<IteratorScope>>(2*_map542.size);
+                  String _key543;
+                  Set<IteratorScope> _val544;
+                  for (int _i545 = 0; _i545 < _map542.size; ++_i545)
+                  {
+                    _key543 = iprot.readString();
+                    {
+                      org.apache.thrift.protocol.TSet _set546 = iprot.readSetBegin();
+                      _val544 = new HashSet<IteratorScope>(2*_set546.size);
+                      IteratorScope _elem547;
+                      for (int _i548 = 0; _i548 < _set546.size; ++_i548)
+                      {
+                        _elem547 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                        _val544.add(_elem547);
+                      }
+                      iprot.readSetEnd();
+                    }
+                    struct.success.put(_key543, _val544);
+                  }
+                  iprot.readMapEnd();
+                }
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaceIterators_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          {
+            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, struct.success.size()));
+            for (Map.Entry<String, Set<IteratorScope>> _iter549 : struct.success.entrySet())
+            {
+              oprot.writeString(_iter549.getKey());
+              {
+                oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, _iter549.getValue().size()));
+                for (IteratorScope _iter550 : _iter549.getValue())
+                {
+                  oprot.writeI32(_iter550.getValue());
+                }
+                oprot.writeSetEnd();
+              }
+            }
+            oprot.writeMapEnd();
+          }
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class listNamespaceIterators_resultTupleSchemeFactory implements SchemeFactory {
+      public listNamespaceIterators_resultTupleScheme getScheme() {
+        return new listNamespaceIterators_resultTupleScheme();
+      }
+    }
+
+    private static class listNamespaceIterators_resultTupleScheme extends TupleScheme<listNamespaceIterators_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, listNamespaceIterators_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch1()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(2);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetSuccess()) {
+          {
+            oprot.writeI32(struct.success.size());
+            for (Map.Entry<String, Set<IteratorScope>> _iter551 : struct.success.entrySet())
+            {
+              oprot.writeString(_iter551.getKey());
+              {
+                oprot.writeI32(_iter551.getValue().size());
+                for (IteratorScope _iter552 : _iter551.getValue())
+                {
+                  oprot.writeI32(_iter552.getValue());
+                }
+              }
+            }
+          }
+        }
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaceIterators_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          {
+            org.apache.thrift.protocol.TMap _map553 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, iprot.readI32());
+            struct.success = new HashMap<String,Set<IteratorScope>>(2*_map553.size);
+            String _key554;
+            Set<IteratorScope> _val555;
+            for (int _i556 = 0; _i556 < _map553.size; ++_i556)
+            {
+              _key554 = iprot.readString();
+              {
+                org.apache.thrift.protocol.TSet _set557 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
+                _val555 = new HashSet<IteratorScope>(2*_set557.size);
+                IteratorScope _elem558;
+                for (int _i559 = 0; _i559 < _set557.size; ++_i559)
+                {
+                  _elem558 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                  _val555.add(_elem558);
+                }
+              }
+              struct.success.put(_key554, _val555);
+            }
+          }
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class checkNamespaceIteratorConflicts_args implements org.apache.thrift.TBase<checkNamespaceIteratorConflicts_args, checkNamespaceIteratorConflicts_args._Fields>, java.io.Serializable, Cloneable, Comparable<checkNamespaceIteratorConflicts_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("checkNamespaceIteratorConflicts_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField SETTING_FIELD_DESC = new org.apache.thrift.protocol.TField("setting", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+    private static final org.apache.thrift.protocol.TField SCOPES_FIELD_DESC = new org.apache.thrift.protocol.TField("scopes", org.apache.thrift.protocol.TType.SET, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new checkNamespaceIteratorConflicts_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new checkNamespaceIteratorConflicts_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+    public IteratorSetting setting; // required
+    public Set<IteratorScope> scopes; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName"),
+      SETTING((short)3, "setting"),
+      SCOPES((short)4, "scopes");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 3: // SETTING
+            return SETTING;
+          case 4: // SCOPES
+            return SCOPES;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.SETTING, new org.apache.thrift.meta_data.FieldMetaData("setting", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class)));
+      tmpMap.put(_Fields.SCOPES, new org.apache.thrift.meta_data.FieldMetaData("scopes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
+              new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, IteratorScope.class))));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkNamespaceIteratorConflicts_args.class, metaDataMap);
+    }
+
+    public checkNamespaceIteratorConflicts_args() {
+    }
+
+    public checkNamespaceIteratorConflicts_args(
+      ByteBuffer login,
+      String namespaceName,
+      IteratorSetting setting,
+      Set<IteratorScope> scopes)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+      this.setting = setting;
+      this.scopes = scopes;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public checkNamespaceIteratorConflicts_args(checkNamespaceIteratorConflicts_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetSetting()) {
+        this.setting = new IteratorSetting(other.setting);
+      }
+      if (other.isSetScopes()) {
+        Set<IteratorScope> __this__scopes = new HashSet<IteratorScope>(other.scopes.size());
+        for (IteratorScope other_element : other.scopes) {
+          __this__scopes.add(other_element);
+        }
+        this.scopes = __this__scopes;
+      }
+    }
+
+    public checkNamespaceIteratorConflicts_args deepCopy() {
+      return new checkNamespaceIteratorConflicts_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+      this.setting = null;
+      this.scopes = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public checkNamespaceIteratorConflicts_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public checkNamespaceIteratorConflicts_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public checkNamespaceIteratorConflicts_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public IteratorSetting getSetting() {
+      return this.setting;
+    }
+
+    public checkNamespaceIteratorConflicts_args setSetting(IteratorSetting setting) {
+      this.setting = setting;
+      return this;
+    }
+
+    public void unsetSetting() {
+      this.setting = null;
+    }
+
+    /** Returns true if field setting is set (has been assigned a value) and false otherwise */
+    public boolean isSetSetting() {
+      return this.setting != null;
+    }
+
+    public void setSettingIsSet(boolean value) {
+      if (!value) {
+        this.setting = null;
+      }
+    }
+
+    public int getScopesSize() {
+      return (this.scopes == null) ? 0 : this.scopes.size();
+    }
+
+    public java.util.Iterator<IteratorScope> getScopesIterator() {
+      return (this.scopes == null) ? null : this.scopes.iterator();
+    }
+
+    public void addToScopes(IteratorScope elem) {
+      if (this.scopes == null) {
+        this.scopes = new HashSet<IteratorScope>();
+      }
+      this.scopes.add(elem);
+    }
+
+    public Set<IteratorScope> getScopes() {
+      return this.scopes;
+    }
+
+    public checkNamespaceIteratorConflicts_args setScopes(Set<IteratorScope> scopes) {
+      this.scopes = scopes;
+      return this;
+    }
+
+    public void unsetScopes() {
+      this.scopes = null;
+    }
+
+    /** Returns true if field scopes is set (has been assigned a value) and false otherwise */
+    public boolean isSetScopes() {
+      return this.scopes != null;
+    }
+
+    public void setScopesIsSet(boolean value) {
+      if (!value) {
+        this.scopes = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case SETTING:
+        if (value == null) {
+          unsetSetting();
+        } else {
+          setSetting((IteratorSetting)value);
+        }
+        break;
+
+      case SCOPES:
+        if (value == null) {
+          unsetScopes();
+        } else {
+          setScopes((Set<IteratorScope>)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case SETTING:
+        return getSetting();
+
+      case SCOPES:
+        return getScopes();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case SETTING:
+        return isSetSetting();
+      case SCOPES:
+        return isSetScopes();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof checkNamespaceIteratorConflicts_args)
+        return this.equals((checkNamespaceIteratorConflicts_args)that);
+      return false;
+    }
+
+    public boolean equals(checkNamespaceIteratorConflicts_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_setting = true && this.isSetSetting();
+      boolean that_present_setting = true && that.isSetSetting();
+      if (this_present_setting || that_present_setting) {
+        if (!(this_present_setting && that_present_setting))
+          return false;
+        if (!this.setting.equals(that.setting))
+          return false;
+      }
+
+      boolean this_present_scopes = true && this.isSetScopes();
+      boolean that_present_scopes = true && that.isSetScopes();
+      if (this_present_scopes || that_present_scopes) {
+        if (!(this_present_scopes && that_present_scopes))
+          return false;
+        if (!this.scopes.equals(that.scopes))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_setting = true && (isSetSetting());
+      list.add(present_setting);
+      if (present_setting)
+        list.add(setting);
+
+      boolean present_scopes = true && (isSetScopes());
+      list.add(present_scopes);
+      if (present_scopes)
+        list.add(scopes);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(checkNamespaceIteratorConflicts_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSetting()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.setting, other.setting);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetScopes()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scopes, other.scopes);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("checkNamespaceIteratorConflicts_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("setting:");
+      if (this.setting == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.setting);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("scopes:");
+      if (this.scopes == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.scopes);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (setting != null) {
+        setting.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class checkNamespaceIteratorConflicts_argsStandardSchemeFactory implements SchemeFactory {
+      public checkNamespaceIteratorConflicts_argsStandardScheme getScheme() {
+        return new checkNamespaceIteratorConflicts_argsStandardScheme();
+      }
+    }
+
+    private static class checkNamespaceIteratorConflicts_argsStandardScheme extends StandardScheme<checkNamespaceIteratorConflicts_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, checkNamespaceIteratorConflicts_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // SETTING
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.setting = new IteratorSetting();
+                struct.setting.read(iprot);
+                struct.setSettingIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // SCOPES
+              if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
+                {
+                  org.apache.thrift.protocol.TSet _set560 = iprot.readSetBegin();
+                  struct.scopes = new HashSet<IteratorScope>(2*_set560.size);
+                  IteratorScope _elem561;
+                  for (int _i562 = 0; _i562 < _set560.size; ++_i562)
+                  {
+                    _elem561 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+                    struct.scopes.add(_elem561);
+                  }
+                  iprot.readSetEnd();
+                }
+                struct.setScopesIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, checkNamespaceIteratorConflicts_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.setting != null) {
+          oprot.writeFieldBegin(SETTING_FIELD_DESC);
+          struct.setting.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.scopes != null) {
+          oprot.writeFieldBegin(SCOPES_FIELD_DESC);
+          {
+            oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, struct.scopes.size()));
+            for (IteratorScope _iter563 : struct.scopes)
+            {
+              oprot.writeI32(_iter563.getValue());
+            }
+            oprot.writeSetEnd();
+          }
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class checkNamespaceIteratorConflicts_argsTupleSchemeFactory implements SchemeFactory {
+      public checkNamespaceIteratorConflicts_argsTupleScheme getScheme() {
+        return new checkNamespaceIteratorConflicts_argsTupleScheme();
+      }
+    }
+
+    private static class checkNamespaceIteratorConflicts_argsTupleScheme extends TupleScheme<checkNamespaceIteratorConflicts_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, checkNamespaceIteratorConflicts_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        if (struct.isSetSetting()) {
+          optionals.set(2);
+        }
+        if (struct.isSetScopes()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetSetting()) {
+          struct.setting.write(oprot);
+        }
+        if (struct.isSetScopes()) {
+          {
+            oprot.writeI32(struct.scopes.size());
+            for (IteratorScope _iter564 : struct.scopes)
+            {
+              oprot.writeI32(_iter564.getValue());
+            }
+          }
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, checkNamespaceIteratorConflicts_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.setting = new IteratorSetting();
+          struct.setting.read(iprot);
+          struct.setSettingIsSet(true);
+        }
+        if (incoming.get(3)) {
+          {
+            org.apache.thrift.protocol.TSet _set565 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
+            struct.scopes = new HashSet<IteratorScope>(2*_set565.size);
+            IteratorScope _elem566;
+            for (int _i567 = 0; _i567 < _set565.size; ++_i567)
+            {
+              _elem566 = org.apache.accumulo.proxy.thrift.IteratorScope.findByValue(iprot.readI32());
+              struct.scopes.add(_elem566);
+            }
+          }
+          struct.setScopesIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class checkNamespaceIteratorConflicts_result implements org.apache.thrift.TBase<checkNamespaceIteratorConflicts_result, checkNamespaceIteratorConflicts_result._Fields>, java.io.Serializable, Cloneable, Comparable<checkNamespaceIteratorConflicts_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("checkNamespaceIteratorConflicts_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new checkNamespaceIteratorConflicts_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new checkNamespaceIteratorConflicts_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkNamespaceIteratorConflicts_result.class, metaDataMap);
+    }
+
+    public checkNamespaceIteratorConflicts_result() {
+    }
+
+    public checkNamespaceIteratorConflicts_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public checkNamespaceIteratorConflicts_result(checkNamespaceIteratorConflicts_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public checkNamespaceIteratorConflicts_result deepCopy() {
+      return new checkNamespaceIteratorConflicts_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public checkNamespaceIteratorConflicts_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public checkNamespaceIteratorConflicts_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public checkNamespaceIteratorConflicts_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof checkNamespaceIteratorConflicts_result)
+        return this.equals((checkNamespaceIteratorConflicts_result)that);
+      return false;
+    }
+
+    public boolean equals(checkNamespaceIteratorConflicts_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(checkNamespaceIteratorConflicts_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("checkNamespaceIteratorConflicts_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class checkNamespaceIteratorConflicts_resultStandardSchemeFactory implements SchemeFactory {
+      public checkNamespaceIteratorConflicts_resultStandardScheme getScheme() {
+        return new checkNamespaceIteratorConflicts_resultStandardScheme();
+      }
+    }
+
+    private static class checkNamespaceIteratorConflicts_resultStandardScheme extends StandardScheme<checkNamespaceIteratorConflicts_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, checkNamespaceIteratorConflicts_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, checkNamespaceIteratorConflicts_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class checkNamespaceIteratorConflicts_resultTupleSchemeFactory implements SchemeFactory {
+      public checkNamespaceIteratorConflicts_resultTupleScheme getScheme() {
+        return new checkNamespaceIteratorConflicts_resultTupleScheme();
+      }
+    }
+
+    private static class checkNamespaceIteratorConflicts_resultTupleScheme extends TupleScheme<checkNamespaceIteratorConflicts_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, checkNamespaceIteratorConflicts_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, checkNamespaceIteratorConflicts_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class addNamespaceConstraint_args implements org.apache.thrift.TBase<addNamespaceConstraint_args, addNamespaceConstraint_args._Fields>, java.io.Serializable, Cloneable, Comparable<addNamespaceConstraint_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addNamespaceConstraint_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField CONSTRAINT_CLASS_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("constraintClassName", org.apache.thrift.protocol.TType.STRING, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new addNamespaceConstraint_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new addNamespaceConstraint_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+    public String constraintClassName; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName"),
+      CONSTRAINT_CLASS_NAME((short)3, "constraintClassName");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 3: // CONSTRAINT_CLASS_NAME
+            return CONSTRAINT_CLASS_NAME;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.CONSTRAINT_CLASS_NAME, new org.apache.thrift.meta_data.FieldMetaData("constraintClassName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addNamespaceConstraint_args.class, metaDataMap);
+    }
+
+    public addNamespaceConstraint_args() {
+    }
+
+    public addNamespaceConstraint_args(
+      ByteBuffer login,
+      String namespaceName,
+      String constraintClassName)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+      this.constraintClassName = constraintClassName;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public addNamespaceConstraint_args(addNamespaceConstraint_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetConstraintClassName()) {
+        this.constraintClassName = other.constraintClassName;
+      }
+    }
+
+    public addNamespaceConstraint_args deepCopy() {
+      return new addNamespaceConstraint_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+      this.constraintClassName = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public addNamespaceConstraint_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public addNamespaceConstraint_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public addNamespaceConstraint_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public String getConstraintClassName() {
+      return this.constraintClassName;
+    }
+
+    public addNamespaceConstraint_args setConstraintClassName(String constraintClassName) {
+      this.constraintClassName = constraintClassName;
+      return this;
+    }
+
+    public void unsetConstraintClassName() {
+      this.constraintClassName = null;
+    }
+
+    /** Returns true if field constraintClassName is set (has been assigned a value) and false otherwise */
+    public boolean isSetConstraintClassName() {
+      return this.constraintClassName != null;
+    }
+
+    public void setConstraintClassNameIsSet(boolean value) {
+      if (!value) {
+        this.constraintClassName = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case CONSTRAINT_CLASS_NAME:
+        if (value == null) {
+          unsetConstraintClassName();
+        } else {
+          setConstraintClassName((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case CONSTRAINT_CLASS_NAME:
+        return getConstraintClassName();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case CONSTRAINT_CLASS_NAME:
+        return isSetConstraintClassName();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof addNamespaceConstraint_args)
+        return this.equals((addNamespaceConstraint_args)that);
+      return false;
+    }
+
+    public boolean equals(addNamespaceConstraint_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_constraintClassName = true && this.isSetConstraintClassName();
+      boolean that_present_constraintClassName = true && that.isSetConstraintClassName();
+      if (this_present_constraintClassName || that_present_constraintClassName) {
+        if (!(this_present_constraintClassName && that_present_constraintClassName))
+          return false;
+        if (!this.constraintClassName.equals(that.constraintClassName))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_constraintClassName = true && (isSetConstraintClassName());
+      list.add(present_constraintClassName);
+      if (present_constraintClassName)
+        list.add(constraintClassName);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(addNamespaceConstraint_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetConstraintClassName()).compareTo(other.isSetConstraintClassName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetConstraintClassName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.constraintClassName, other.constraintClassName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("addNamespaceConstraint_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("constraintClassName:");
+      if (this.constraintClassName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.constraintClassName);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class addNamespaceConstraint_argsStandardSchemeFactory implements SchemeFactory {
+      public addNamespaceConstraint_argsStandardScheme getScheme() {
+        return new addNamespaceConstraint_argsStandardScheme();
+      }
+    }
+
+    private static class addNamespaceConstraint_argsStandardScheme extends StandardScheme<addNamespaceConstraint_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, addNamespaceConstraint_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // CONSTRAINT_CLASS_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.constraintClassName = iprot.readString();
+                struct.setConstraintClassNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, addNamespaceConstraint_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.constraintClassName != null) {
+          oprot.writeFieldBegin(CONSTRAINT_CLASS_NAME_FIELD_DESC);
+          oprot.writeString(struct.constraintClassName);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class addNamespaceConstraint_argsTupleSchemeFactory implements SchemeFactory {
+      public addNamespaceConstraint_argsTupleScheme getScheme() {
+        return new addNamespaceConstraint_argsTupleScheme();
+      }
+    }
+
+    private static class addNamespaceConstraint_argsTupleScheme extends TupleScheme<addNamespaceConstraint_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, addNamespaceConstraint_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        if (struct.isSetConstraintClassName()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetConstraintClassName()) {
+          oprot.writeString(struct.constraintClassName);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, addNamespaceConstraint_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.constraintClassName = iprot.readString();
+          struct.setConstraintClassNameIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class addNamespaceConstraint_result implements org.apache.thrift.TBase<addNamespaceConstraint_result, addNamespaceConstraint_result._Fields>, java.io.Serializable, Cloneable, Comparable<addNamespaceConstraint_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addNamespaceConstraint_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.I32, (short)0);
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new addNamespaceConstraint_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new addNamespaceConstraint_resultTupleSchemeFactory());
+    }
+
+    public int success; // required
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addNamespaceConstraint_result.class, metaDataMap);
+    }
+
+    public addNamespaceConstraint_result() {
+    }
+
+    public addNamespaceConstraint_result(
+      int success,
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public addNamespaceConstraint_result(addNamespaceConstraint_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public addNamespaceConstraint_result deepCopy() {
+      return new addNamespaceConstraint_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public addNamespaceConstraint_result setSuccess(int success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public addNamespaceConstraint_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public addNamespaceConstraint_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public addNamespaceConstraint_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof addNamespaceConstraint_result)
+        return this.equals((addNamespaceConstraint_result)that);
+      return false;
+    }
+
+    public boolean equals(addNamespaceConstraint_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true;
+      boolean that_present_success = true;
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (this.success != that.success)
+          return false;
+      }
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(addNamespaceConstraint_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("addNamespaceConstraint_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class addNamespaceConstraint_resultStandardSchemeFactory implements SchemeFactory {
+      public addNamespaceConstraint_resultStandardScheme getScheme() {
+        return new addNamespaceConstraint_resultStandardScheme();
+      }
+    }
+
+    private static class addNamespaceConstraint_resultStandardScheme extends StandardScheme<addNamespaceConstraint_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, addNamespaceConstraint_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.success = iprot.readI32();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, addNamespaceConstraint_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeI32(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class addNamespaceConstraint_resultTupleSchemeFactory implements SchemeFactory {
+      public addNamespaceConstraint_resultTupleScheme getScheme() {
+        return new addNamespaceConstraint_resultTupleScheme();
+      }
+    }
+
+    private static class addNamespaceConstraint_resultTupleScheme extends TupleScheme<addNamespaceConstraint_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, addNamespaceConstraint_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch1()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(2);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetSuccess()) {
+          oprot.writeI32(struct.success);
+        }
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, addNamespaceConstraint_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.success = iprot.readI32();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class removeNamespaceConstraint_args implements org.apache.thrift.TBase<removeNamespaceConstraint_args, removeNamespaceConstraint_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceConstraint_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceConstraint_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField ID_FIELD_DESC = new org.apache.thrift.protocol.TField("id", org.apache.thrift.protocol.TType.I32, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new removeNamespaceConstraint_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new removeNamespaceConstraint_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+    public int id; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName"),
+      ID((short)3, "id");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 3: // ID
+            return ID;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __ID_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.ID, new org.apache.thrift.meta_data.FieldMetaData("id", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceConstraint_args.class, metaDataMap);
+    }
+
+    public removeNamespaceConstraint_args() {
+    }
+
+    public removeNamespaceConstraint_args(
+      ByteBuffer login,
+      String namespaceName,
+      int id)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+      this.id = id;
+      setIdIsSet(true);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public removeNamespaceConstraint_args(removeNamespaceConstraint_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      this.id = other.id;
+    }
+
+    public removeNamespaceConstraint_args deepCopy() {
+      return new removeNamespaceConstraint_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+      setIdIsSet(false);
+      this.id = 0;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public removeNamespaceConstraint_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public removeNamespaceConstraint_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public removeNamespaceConstraint_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public int getId() {
+      return this.id;
+    }
+
+    public removeNamespaceConstraint_args setId(int id) {
+      this.id = id;
+      setIdIsSet(true);
+      return this;
+    }
+
+    public void unsetId() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ID_ISSET_ID);
+    }
+
+    /** Returns true if field id is set (has been assigned a value) and false otherwise */
+    public boolean isSetId() {
+      return EncodingUtils.testBit(__isset_bitfield, __ID_ISSET_ID);
+    }
+
+    public void setIdIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ID_ISSET_ID, value);
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case ID:
+        if (value == null) {
+          unsetId();
+        } else {
+          setId((Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case ID:
+        return getId();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case ID:
+        return isSetId();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof removeNamespaceConstraint_args)
+        return this.equals((removeNamespaceConstraint_args)that);
+      return false;
+    }
+
+    public boolean equals(removeNamespaceConstraint_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_id = true;
+      boolean that_present_id = true;
+      if (this_present_id || that_present_id) {
+        if (!(this_present_id && that_present_id))
+          return false;
+        if (this.id != that.id)
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_id = true;
+      list.add(present_id);
+      if (present_id)
+        list.add(id);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(removeNamespaceConstraint_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetId()).compareTo(other.isSetId());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetId()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.id, other.id);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("removeNamespaceConstraint_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("id:");
+      sb.append(this.id);
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class removeNamespaceConstraint_argsStandardSchemeFactory implements SchemeFactory {
+      public removeNamespaceConstraint_argsStandardScheme getScheme() {
+        return new removeNamespaceConstraint_argsStandardScheme();
+      }
+    }
+
+    private static class removeNamespaceConstraint_argsStandardScheme extends StandardScheme<removeNamespaceConstraint_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, removeNamespaceConstraint_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // ID
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.id = iprot.readI32();
+                struct.setIdIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceConstraint_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldBegin(ID_FIELD_DESC);
+        oprot.writeI32(struct.id);
+        oprot.writeFieldEnd();
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class removeNamespaceConstraint_argsTupleSchemeFactory implements SchemeFactory {
+      public removeNamespaceConstraint_argsTupleScheme getScheme() {
+        return new removeNamespaceConstraint_argsTupleScheme();
+      }
+    }
+
+    private static class removeNamespaceConstraint_argsTupleScheme extends TupleScheme<removeNamespaceConstraint_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, removeNamespaceConstraint_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        if (struct.isSetId()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetId()) {
+          oprot.writeI32(struct.id);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceConstraint_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.id = iprot.readI32();
+          struct.setIdIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class removeNamespaceConstraint_result implements org.apache.thrift.TBase<removeNamespaceConstraint_result, removeNamespaceConstraint_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceConstraint_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeNamespaceConstraint_result");
+
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new removeNamespaceConstraint_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new removeNamespaceConstraint_resultTupleSchemeFactory());
+    }
+
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceConstraint_result.class, metaDataMap);
+    }
+
+    public removeNamespaceConstraint_result() {
+    }
+
+    public removeNamespaceConstraint_result(
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public removeNamespaceConstraint_result(removeNamespaceConstraint_result other) {
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public removeNamespaceConstraint_result deepCopy() {
+      return new removeNamespaceConstraint_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public removeNamespaceConstraint_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public removeNamespaceConstraint_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public removeNamespaceConstraint_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof removeNamespaceConstraint_result)
+        return this.equals((removeNamespaceConstraint_result)that);
+      return false;
+    }
+
+    public boolean equals(removeNamespaceConstraint_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(removeNamespaceConstraint_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("removeNamespaceConstraint_result(");
+      boolean first = true;
+
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class removeNamespaceConstraint_resultStandardSchemeFactory implements SchemeFactory {
+      public removeNamespaceConstraint_resultStandardScheme getScheme() {
+        return new removeNamespaceConstraint_resultStandardScheme();
+      }
+    }
+
+    private static class removeNamespaceConstraint_resultStandardScheme extends StandardScheme<removeNamespaceConstraint_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, removeNamespaceConstraint_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, removeNamespaceConstraint_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class removeNamespaceConstraint_resultTupleSchemeFactory implements SchemeFactory {
+      public removeNamespaceConstraint_resultTupleScheme getScheme() {
+        return new removeNamespaceConstraint_resultTupleScheme();
+      }
+    }
+
+    private static class removeNamespaceConstraint_resultTupleScheme extends TupleScheme<removeNamespaceConstraint_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, removeNamespaceConstraint_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetOuch1()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, removeNamespaceConstraint_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class listNamespaceConstraints_args implements org.apache.thrift.TBase<listNamespaceConstraints_args, listNamespaceConstraints_args._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaceConstraints_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaceConstraints_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new listNamespaceConstraints_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new listNamespaceConstraints_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaceConstraints_args.class, metaDataMap);
+    }
+
+    public listNamespaceConstraints_args() {
+    }
+
+    public listNamespaceConstraints_args(
+      ByteBuffer login,
+      String namespaceName)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public listNamespaceConstraints_args(listNamespaceConstraints_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+    }
+
+    public listNamespaceConstraints_args deepCopy() {
+      return new listNamespaceConstraints_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public listNamespaceConstraints_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public listNamespaceConstraints_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public listNamespaceConstraints_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof listNamespaceConstraints_args)
+        return this.equals((listNamespaceConstraints_args)that);
+      return false;
+    }
+
+    public boolean equals(listNamespaceConstraints_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(listNamespaceConstraints_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("listNamespaceConstraints_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class listNamespaceConstraints_argsStandardSchemeFactory implements SchemeFactory {
+      public listNamespaceConstraints_argsStandardScheme getScheme() {
+        return new listNamespaceConstraints_argsStandardScheme();
+      }
+    }
+
+    private static class listNamespaceConstraints_argsStandardScheme extends StandardScheme<listNamespaceConstraints_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, listNamespaceConstraints_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaceConstraints_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class listNamespaceConstraints_argsTupleSchemeFactory implements SchemeFactory {
+      public listNamespaceConstraints_argsTupleScheme getScheme() {
+        return new listNamespaceConstraints_argsTupleScheme();
+      }
+    }
+
+    private static class listNamespaceConstraints_argsTupleScheme extends TupleScheme<listNamespaceConstraints_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, listNamespaceConstraints_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaceConstraints_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class listNamespaceConstraints_result implements org.apache.thrift.TBase<listNamespaceConstraints_result, listNamespaceConstraints_result._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaceConstraints_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("listNamespaceConstraints_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.MAP, (short)0);
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new listNamespaceConstraints_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new listNamespaceConstraints_resultTupleSchemeFactory());
+    }
+
+    public Map<String,Integer> success; // required
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
+              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
+              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaceConstraints_result.class, metaDataMap);
+    }
+
+    public listNamespaceConstraints_result() {
+    }
+
+    public listNamespaceConstraints_result(
+      Map<String,Integer> success,
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.success = success;
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public listNamespaceConstraints_result(listNamespaceConstraints_result other) {
+      if (other.isSetSuccess()) {
+        Map<String,Integer> __this__success = new HashMap<String,Integer>(other.success);
+        this.success = __this__success;
+      }
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public listNamespaceConstraints_result deepCopy() {
+      return new listNamespaceConstraints_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public int getSuccessSize() {
+      return (this.success == null) ? 0 : this.success.size();
+    }
+
+    public void putToSuccess(String key, int val) {
+      if (this.success == null) {
+        this.success = new HashMap<String,Integer>();
+      }
+      this.success.put(key, val);
+    }
+
+    public Map<String,Integer> getSuccess() {
+      return this.success;
+    }
+
+    public listNamespaceConstraints_result setSuccess(Map<String,Integer> success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public listNamespaceConstraints_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public listNamespaceConstraints_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public listNamespaceConstraints_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Map<String,Integer>)value);
+        }
+        break;
+
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof listNamespaceConstraints_result)
+        return this.equals((listNamespaceConstraints_result)that);
+      return false;
+    }
+
+    public boolean equals(listNamespaceConstraints_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true && (isSetSuccess());
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(listNamespaceConstraints_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("listNamespaceConstraints_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class listNamespaceConstraints_resultStandardSchemeFactory implements SchemeFactory {
+      public listNamespaceConstraints_resultStandardScheme getScheme() {
+        return new listNamespaceConstraints_resultStandardScheme();
+      }
+    }
+
+    private static class listNamespaceConstraints_resultStandardScheme extends StandardScheme<listNamespaceConstraints_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, listNamespaceConstraints_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
+                {
+                  org.apache.thrift.protocol.TMap _map568 = iprot.readMapBegin();
+                  struct.success = new HashMap<String,Integer>(2*_map568.size);
+                  String _key569;
+                  int _val570;
+                  for (int _i571 = 0; _i571 < _map568.size; ++_i571)
+                  {
+                    _key569 = iprot.readString();
+                    _val570 = iprot.readI32();
+                    struct.success.put(_key569, _val570);
+                  }
+                  iprot.readMapEnd();
+                }
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, listNamespaceConstraints_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          {
+            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, struct.success.size()));
+            for (Map.Entry<String, Integer> _iter572 : struct.success.entrySet())
+            {
+              oprot.writeString(_iter572.getKey());
+              oprot.writeI32(_iter572.getValue());
+            }
+            oprot.writeMapEnd();
+          }
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class listNamespaceConstraints_resultTupleSchemeFactory implements SchemeFactory {
+      public listNamespaceConstraints_resultTupleScheme getScheme() {
+        return new listNamespaceConstraints_resultTupleScheme();
+      }
+    }
+
+    private static class listNamespaceConstraints_resultTupleScheme extends TupleScheme<listNamespaceConstraints_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, listNamespaceConstraints_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch1()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(2);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetSuccess()) {
+          {
+            oprot.writeI32(struct.success.size());
+            for (Map.Entry<String, Integer> _iter573 : struct.success.entrySet())
+            {
+              oprot.writeString(_iter573.getKey());
+              oprot.writeI32(_iter573.getValue());
+            }
+          }
+        }
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, listNamespaceConstraints_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          {
+            org.apache.thrift.protocol.TMap _map574 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.I32, iprot.readI32());
+            struct.success = new HashMap<String,Integer>(2*_map574.size);
+            String _key575;
+            int _val576;
+            for (int _i577 = 0; _i577 < _map574.size; ++_i577)
+            {
+              _key575 = iprot.readString();
+              _val576 = iprot.readI32();
+              struct.success.put(_key575, _val576);
+            }
+          }
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class testNamespaceClassLoad_args implements org.apache.thrift.TBase<testNamespaceClassLoad_args, testNamespaceClassLoad_args._Fields>, java.io.Serializable, Cloneable, Comparable<testNamespaceClassLoad_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("testNamespaceClassLoad_args");
+
+    private static final org.apache.thrift.protocol.TField LOGIN_FIELD_DESC = new org.apache.thrift.protocol.TField("login", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField NAMESPACE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("namespaceName", org.apache.thrift.protocol.TType.STRING, (short)2);
+    private static final org.apache.thrift.protocol.TField CLASS_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("className", org.apache.thrift.protocol.TType.STRING, (short)3);
+    private static final org.apache.thrift.protocol.TField AS_TYPE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("asTypeName", org.apache.thrift.protocol.TType.STRING, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new testNamespaceClassLoad_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new testNamespaceClassLoad_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer login; // required
+    public String namespaceName; // required
+    public String className; // required
+    public String asTypeName; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      LOGIN((short)1, "login"),
+      NAMESPACE_NAME((short)2, "namespaceName"),
+      CLASS_NAME((short)3, "className"),
+      AS_TYPE_NAME((short)4, "asTypeName");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // LOGIN
+            return LOGIN;
+          case 2: // NAMESPACE_NAME
+            return NAMESPACE_NAME;
+          case 3: // CLASS_NAME
+            return CLASS_NAME;
+          case 4: // AS_TYPE_NAME
+            return AS_TYPE_NAME;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.LOGIN, new org.apache.thrift.meta_data.FieldMetaData("login", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.NAMESPACE_NAME, new org.apache.thrift.meta_data.FieldMetaData("namespaceName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.CLASS_NAME, new org.apache.thrift.meta_data.FieldMetaData("className", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      tmpMap.put(_Fields.AS_TYPE_NAME, new org.apache.thrift.meta_data.FieldMetaData("asTypeName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testNamespaceClassLoad_args.class, metaDataMap);
+    }
+
+    public testNamespaceClassLoad_args() {
+    }
+
+    public testNamespaceClassLoad_args(
+      ByteBuffer login,
+      String namespaceName,
+      String className,
+      String asTypeName)
+    {
+      this();
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      this.namespaceName = namespaceName;
+      this.className = className;
+      this.asTypeName = asTypeName;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public testNamespaceClassLoad_args(testNamespaceClassLoad_args other) {
+      if (other.isSetLogin()) {
+        this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
+      }
+      if (other.isSetNamespaceName()) {
+        this.namespaceName = other.namespaceName;
+      }
+      if (other.isSetClassName()) {
+        this.className = other.className;
+      }
+      if (other.isSetAsTypeName()) {
+        this.asTypeName = other.asTypeName;
+      }
+    }
+
+    public testNamespaceClassLoad_args deepCopy() {
+      return new testNamespaceClassLoad_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.login = null;
+      this.namespaceName = null;
+      this.className = null;
+      this.asTypeName = null;
+    }
+
+    public byte[] getLogin() {
+      setLogin(org.apache.thrift.TBaseHelper.rightSize(login));
+      return login == null ? null : login.array();
+    }
+
+    public ByteBuffer bufferForLogin() {
+      return org.apache.thrift.TBaseHelper.copyBinary(login);
+    }
+
+    public testNamespaceClassLoad_args setLogin(byte[] login) {
+      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      return this;
+    }
+
+    public testNamespaceClassLoad_args setLogin(ByteBuffer login) {
+      this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
+      return this;
+    }
+
+    public void unsetLogin() {
+      this.login = null;
+    }
+
+    /** Returns true if field login is set (has been assigned a value) and false otherwise */
+    public boolean isSetLogin() {
+      return this.login != null;
+    }
+
+    public void setLoginIsSet(boolean value) {
+      if (!value) {
+        this.login = null;
+      }
+    }
+
+    public String getNamespaceName() {
+      return this.namespaceName;
+    }
+
+    public testNamespaceClassLoad_args setNamespaceName(String namespaceName) {
+      this.namespaceName = namespaceName;
+      return this;
+    }
+
+    public void unsetNamespaceName() {
+      this.namespaceName = null;
+    }
+
+    /** Returns true if field namespaceName is set (has been assigned a value) and false otherwise */
+    public boolean isSetNamespaceName() {
+      return this.namespaceName != null;
+    }
+
+    public void setNamespaceNameIsSet(boolean value) {
+      if (!value) {
+        this.namespaceName = null;
+      }
+    }
+
+    public String getClassName() {
+      return this.className;
+    }
+
+    public testNamespaceClassLoad_args setClassName(String className) {
+      this.className = className;
+      return this;
+    }
+
+    public void unsetClassName() {
+      this.className = null;
+    }
+
+    /** Returns true if field className is set (has been assigned a value) and false otherwise */
+    public boolean isSetClassName() {
+      return this.className != null;
+    }
+
+    public void setClassNameIsSet(boolean value) {
+      if (!value) {
+        this.className = null;
+      }
+    }
+
+    public String getAsTypeName() {
+      return this.asTypeName;
+    }
+
+    public testNamespaceClassLoad_args setAsTypeName(String asTypeName) {
+      this.asTypeName = asTypeName;
+      return this;
+    }
+
+    public void unsetAsTypeName() {
+      this.asTypeName = null;
+    }
+
+    /** Returns true if field asTypeName is set (has been assigned a value) and false otherwise */
+    public boolean isSetAsTypeName() {
+      return this.asTypeName != null;
+    }
+
+    public void setAsTypeNameIsSet(boolean value) {
+      if (!value) {
+        this.asTypeName = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case LOGIN:
+        if (value == null) {
+          unsetLogin();
+        } else {
+          setLogin((ByteBuffer)value);
+        }
+        break;
+
+      case NAMESPACE_NAME:
+        if (value == null) {
+          unsetNamespaceName();
+        } else {
+          setNamespaceName((String)value);
+        }
+        break;
+
+      case CLASS_NAME:
+        if (value == null) {
+          unsetClassName();
+        } else {
+          setClassName((String)value);
+        }
+        break;
+
+      case AS_TYPE_NAME:
+        if (value == null) {
+          unsetAsTypeName();
+        } else {
+          setAsTypeName((String)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case LOGIN:
+        return getLogin();
+
+      case NAMESPACE_NAME:
+        return getNamespaceName();
+
+      case CLASS_NAME:
+        return getClassName();
+
+      case AS_TYPE_NAME:
+        return getAsTypeName();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case LOGIN:
+        return isSetLogin();
+      case NAMESPACE_NAME:
+        return isSetNamespaceName();
+      case CLASS_NAME:
+        return isSetClassName();
+      case AS_TYPE_NAME:
+        return isSetAsTypeName();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof testNamespaceClassLoad_args)
+        return this.equals((testNamespaceClassLoad_args)that);
+      return false;
+    }
+
+    public boolean equals(testNamespaceClassLoad_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_login = true && this.isSetLogin();
+      boolean that_present_login = true && that.isSetLogin();
+      if (this_present_login || that_present_login) {
+        if (!(this_present_login && that_present_login))
+          return false;
+        if (!this.login.equals(that.login))
+          return false;
+      }
+
+      boolean this_present_namespaceName = true && this.isSetNamespaceName();
+      boolean that_present_namespaceName = true && that.isSetNamespaceName();
+      if (this_present_namespaceName || that_present_namespaceName) {
+        if (!(this_present_namespaceName && that_present_namespaceName))
+          return false;
+        if (!this.namespaceName.equals(that.namespaceName))
+          return false;
+      }
+
+      boolean this_present_className = true && this.isSetClassName();
+      boolean that_present_className = true && that.isSetClassName();
+      if (this_present_className || that_present_className) {
+        if (!(this_present_className && that_present_className))
+          return false;
+        if (!this.className.equals(that.className))
+          return false;
+      }
+
+      boolean this_present_asTypeName = true && this.isSetAsTypeName();
+      boolean that_present_asTypeName = true && that.isSetAsTypeName();
+      if (this_present_asTypeName || that_present_asTypeName) {
+        if (!(this_present_asTypeName && that_present_asTypeName))
+          return false;
+        if (!this.asTypeName.equals(that.asTypeName))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_login = true && (isSetLogin());
+      list.add(present_login);
+      if (present_login)
+        list.add(login);
+
+      boolean present_namespaceName = true && (isSetNamespaceName());
+      list.add(present_namespaceName);
+      if (present_namespaceName)
+        list.add(namespaceName);
+
+      boolean present_className = true && (isSetClassName());
+      list.add(present_className);
+      if (present_className)
+        list.add(className);
+
+      boolean present_asTypeName = true && (isSetAsTypeName());
+      list.add(present_asTypeName);
+      if (present_asTypeName)
+        list.add(asTypeName);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(testNamespaceClassLoad_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetLogin()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.login, other.login);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNamespaceName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.namespaceName, other.namespaceName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetClassName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.className, other.className);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetAsTypeName()).compareTo(other.isSetAsTypeName());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetAsTypeName()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.asTypeName, other.asTypeName);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("testNamespaceClassLoad_args(");
+      boolean first = true;
+
+      sb.append("login:");
+      if (this.login == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.login, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("namespaceName:");
+      if (this.namespaceName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.namespaceName);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("className:");
+      if (this.className == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.className);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("asTypeName:");
+      if (this.asTypeName == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.asTypeName);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class testNamespaceClassLoad_argsStandardSchemeFactory implements SchemeFactory {
+      public testNamespaceClassLoad_argsStandardScheme getScheme() {
+        return new testNamespaceClassLoad_argsStandardScheme();
+      }
+    }
+
+    private static class testNamespaceClassLoad_argsStandardScheme extends StandardScheme<testNamespaceClassLoad_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, testNamespaceClassLoad_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // LOGIN
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.login = iprot.readBinary();
+                struct.setLoginIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NAMESPACE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.namespaceName = iprot.readString();
+                struct.setNamespaceNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // CLASS_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.className = iprot.readString();
+                struct.setClassNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // AS_TYPE_NAME
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.asTypeName = iprot.readString();
+                struct.setAsTypeNameIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, testNamespaceClassLoad_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.login != null) {
+          oprot.writeFieldBegin(LOGIN_FIELD_DESC);
+          oprot.writeBinary(struct.login);
+          oprot.writeFieldEnd();
+        }
+        if (struct.namespaceName != null) {
+          oprot.writeFieldBegin(NAMESPACE_NAME_FIELD_DESC);
+          oprot.writeString(struct.namespaceName);
+          oprot.writeFieldEnd();
+        }
+        if (struct.className != null) {
+          oprot.writeFieldBegin(CLASS_NAME_FIELD_DESC);
+          oprot.writeString(struct.className);
+          oprot.writeFieldEnd();
+        }
+        if (struct.asTypeName != null) {
+          oprot.writeFieldBegin(AS_TYPE_NAME_FIELD_DESC);
+          oprot.writeString(struct.asTypeName);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class testNamespaceClassLoad_argsTupleSchemeFactory implements SchemeFactory {
+      public testNamespaceClassLoad_argsTupleScheme getScheme() {
+        return new testNamespaceClassLoad_argsTupleScheme();
+      }
+    }
+
+    private static class testNamespaceClassLoad_argsTupleScheme extends TupleScheme<testNamespaceClassLoad_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, testNamespaceClassLoad_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetLogin()) {
+          optionals.set(0);
+        }
+        if (struct.isSetNamespaceName()) {
+          optionals.set(1);
+        }
+        if (struct.isSetClassName()) {
+          optionals.set(2);
+        }
+        if (struct.isSetAsTypeName()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetLogin()) {
+          oprot.writeBinary(struct.login);
+        }
+        if (struct.isSetNamespaceName()) {
+          oprot.writeString(struct.namespaceName);
+        }
+        if (struct.isSetClassName()) {
+          oprot.writeString(struct.className);
+        }
+        if (struct.isSetAsTypeName()) {
+          oprot.writeString(struct.asTypeName);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, testNamespaceClassLoad_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.login = iprot.readBinary();
+          struct.setLoginIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.namespaceName = iprot.readString();
+          struct.setNamespaceNameIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.className = iprot.readString();
+          struct.setClassNameIsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.asTypeName = iprot.readString();
+          struct.setAsTypeNameIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class testNamespaceClassLoad_result implements org.apache.thrift.TBase<testNamespaceClassLoad_result, testNamespaceClassLoad_result._Fields>, java.io.Serializable, Cloneable, Comparable<testNamespaceClassLoad_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("testNamespaceClassLoad_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
+    private static final org.apache.thrift.protocol.TField OUCH1_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch1", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField OUCH3_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch3", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new testNamespaceClassLoad_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new testNamespaceClassLoad_resultTupleSchemeFactory());
+    }
+
+    public boolean success; // required
+    public AccumuloException ouch1; // required
+    public AccumuloSecurityException ouch2; // required
+    public NamespaceNotFoundException ouch3; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      OUCH1((short)1, "ouch1"),
+      OUCH2((short)2, "ouch2"),
+      OUCH3((short)3, "ouch3");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // OUCH1
+            return OUCH1;
+          case 2: // OUCH2
+            return OUCH2;
+          case 3: // OUCH3
+            return OUCH3;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
+      tmpMap.put(_Fields.OUCH1, new org.apache.thrift.meta_data.FieldMetaData("ouch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH2, new org.apache.thrift.meta_data.FieldMetaData("ouch2", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.OUCH3, new org.apache.thrift.meta_data.FieldMetaData("ouch3", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testNamespaceClassLoad_result.class, metaDataMap);
+    }
+
+    public testNamespaceClassLoad_result() {
+    }
+
+    public testNamespaceClassLoad_result(
+      boolean success,
+      AccumuloException ouch1,
+      AccumuloSecurityException ouch2,
+      NamespaceNotFoundException ouch3)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch1 = ouch1;
+      this.ouch2 = ouch2;
+      this.ouch3 = ouch3;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public testNamespaceClassLoad_result(testNamespaceClassLoad_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch1()) {
+        this.ouch1 = new AccumuloException(other.ouch1);
+      }
+      if (other.isSetOuch2()) {
+        this.ouch2 = new AccumuloSecurityException(other.ouch2);
+      }
+      if (other.isSetOuch3()) {
+        this.ouch3 = new NamespaceNotFoundException(other.ouch3);
+      }
+    }
+
+    public testNamespaceClassLoad_result deepCopy() {
+      return new testNamespaceClassLoad_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = false;
+      this.ouch1 = null;
+      this.ouch2 = null;
+      this.ouch3 = null;
+    }
+
+    public boolean isSuccess() {
+      return this.success;
+    }
+
+    public testNamespaceClassLoad_result setSuccess(boolean success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public AccumuloException getOuch1() {
+      return this.ouch1;
+    }
+
+    public testNamespaceClassLoad_result setOuch1(AccumuloException ouch1) {
+      this.ouch1 = ouch1;
+      return this;
+    }
+
+    public void unsetOuch1() {
+      this.ouch1 = null;
+    }
+
+    /** Returns true if field ouch1 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch1() {
+      return this.ouch1 != null;
+    }
+
+    public void setOuch1IsSet(boolean value) {
+      if (!value) {
+        this.ouch1 = null;
+      }
+    }
+
+    public AccumuloSecurityException getOuch2() {
+      return this.ouch2;
+    }
+
+    public testNamespaceClassLoad_result setOuch2(AccumuloSecurityException ouch2) {
+      this.ouch2 = ouch2;
+      return this;
+    }
+
+    public void unsetOuch2() {
+      this.ouch2 = null;
+    }
+
+    /** Returns true if field ouch2 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch2() {
+      return this.ouch2 != null;
+    }
+
+    public void setOuch2IsSet(boolean value) {
+      if (!value) {
+        this.ouch2 = null;
+      }
+    }
+
+    public NamespaceNotFoundException getOuch3() {
+      return this.ouch3;
+    }
+
+    public testNamespaceClassLoad_result setOuch3(NamespaceNotFoundException ouch3) {
+      this.ouch3 = ouch3;
+      return this;
+    }
+
+    public void unsetOuch3() {
+      this.ouch3 = null;
+    }
+
+    /** Returns true if field ouch3 is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch3() {
+      return this.ouch3 != null;
+    }
+
+    public void setOuch3IsSet(boolean value) {
+      if (!value) {
+        this.ouch3 = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Boolean)value);
+        }
+        break;
+
+      case OUCH1:
+        if (value == null) {
+          unsetOuch1();
+        } else {
+          setOuch1((AccumuloException)value);
+        }
+        break;
+
+      case OUCH2:
+        if (value == null) {
+          unsetOuch2();
+        } else {
+          setOuch2((AccumuloSecurityException)value);
+        }
+        break;
+
+      case OUCH3:
+        if (value == null) {
+          unsetOuch3();
+        } else {
+          setOuch3((NamespaceNotFoundException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return isSuccess();
+
+      case OUCH1:
+        return getOuch1();
+
+      case OUCH2:
+        return getOuch2();
+
+      case OUCH3:
+        return getOuch3();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH1:
+        return isSetOuch1();
+      case OUCH2:
+        return isSetOuch2();
+      case OUCH3:
+        return isSetOuch3();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof testNamespaceClassLoad_result)
+        return this.equals((testNamespaceClassLoad_result)that);
+      return false;
+    }
+
+    public boolean equals(testNamespaceClassLoad_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true;
+      boolean that_present_success = true;
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (this.success != that.success)
+          return false;
+      }
+
+      boolean this_present_ouch1 = true && this.isSetOuch1();
+      boolean that_present_ouch1 = true && that.isSetOuch1();
+      if (this_present_ouch1 || that_present_ouch1) {
+        if (!(this_present_ouch1 && that_present_ouch1))
+          return false;
+        if (!this.ouch1.equals(that.ouch1))
+          return false;
+      }
+
+      boolean this_present_ouch2 = true && this.isSetOuch2();
+      boolean that_present_ouch2 = true && that.isSetOuch2();
+      if (this_present_ouch2 || that_present_ouch2) {
+        if (!(this_present_ouch2 && that_present_ouch2))
+          return false;
+        if (!this.ouch2.equals(that.ouch2))
+          return false;
+      }
+
+      boolean this_present_ouch3 = true && this.isSetOuch3();
+      boolean that_present_ouch3 = true && that.isSetOuch3();
+      if (this_present_ouch3 || that_present_ouch3) {
+        if (!(this_present_ouch3 && that_present_ouch3))
+          return false;
+        if (!this.ouch3.equals(that.ouch3))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      List<Object> list = new ArrayList<Object>();
+
+      boolean present_success = true;
+      list.add(present_success);
+      if (present_success)
+        list.add(success);
+
+      boolean present_ouch1 = true && (isSetOuch1());
+      list.add(present_ouch1);
+      if (present_ouch1)
+        list.add(ouch1);
+
+      boolean present_ouch2 = true && (isSetOuch2());
+      list.add(present_ouch2);
+      if (present_ouch2)
+        list.add(ouch2);
+
+      boolean present_ouch3 = true && (isSetOuch3());
+      list.add(present_ouch3);
+      if (present_ouch3)
+        list.add(ouch3);
+
+      return list.hashCode();
+    }
+
+    @Override
+    public int compareTo(testNamespaceClassLoad_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch1()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch1, other.ouch1);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch2()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch2, other.ouch2);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch3()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch3, other.ouch3);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("testNamespaceClassLoad_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch1:");
+      if (this.ouch1 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch1);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch2:");
+      if (this.ouch2 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch2);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch3:");
+      if (this.ouch3 == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch3);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+        __isset_bitfield = 0;
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class testNamespaceClassLoad_resultStandardSchemeFactory implements SchemeFactory {
+      public testNamespaceClassLoad_resultStandardScheme getScheme() {
+        return new testNamespaceClassLoad_resultStandardScheme();
+      }
+    }
+
+    private static class testNamespaceClassLoad_resultStandardScheme extends StandardScheme<testNamespaceClassLoad_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, testNamespaceClassLoad_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
+                struct.success = iprot.readBool();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH1
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch1 = new AccumuloException();
+                struct.ouch1.read(iprot);
+                struct.setOuch1IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // OUCH2
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch2 = new AccumuloSecurityException();
+                struct.ouch2.read(iprot);
+                struct.setOuch2IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // OUCH3
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch3 = new NamespaceNotFoundException();
+                struct.ouch3.read(iprot);
+                struct.setOuch3IsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, testNamespaceClassLoad_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeBool(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch1 != null) {
+          oprot.writeFieldBegin(OUCH1_FIELD_DESC);
+          struct.ouch1.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch2 != null) {
+          oprot.writeFieldBegin(OUCH2_FIELD_DESC);
+          struct.ouch2.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch3 != null) {
+          oprot.writeFieldBegin(OUCH3_FIELD_DESC);
+          struct.ouch3.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class testNamespaceClassLoad_resultTupleSchemeFactory implements SchemeFactory {
+      public testNamespaceClassLoad_resultTupleScheme getScheme() {
+        return new testNamespaceClassLoad_resultTupleScheme();
+      }
+    }
+
+    private static class testNamespaceClassLoad_resultTupleScheme extends TupleScheme<testNamespaceClassLoad_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, testNamespaceClassLoad_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch1()) {
+          optionals.set(1);
+        }
+        if (struct.isSetOuch2()) {
+          optionals.set(2);
+        }
+        if (struct.isSetOuch3()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetSuccess()) {
+          oprot.writeBool(struct.success);
+        }
+        if (struct.isSetOuch1()) {
+          struct.ouch1.write(oprot);
+        }
+        if (struct.isSetOuch2()) {
+          struct.ouch2.write(oprot);
+        }
+        if (struct.isSetOuch3()) {
+          struct.ouch3.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, testNamespaceClassLoad_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.success = iprot.readBool();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch1 = new AccumuloException();
+          struct.ouch1.read(iprot);
+          struct.setOuch1IsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ouch2 = new AccumuloSecurityException();
+          struct.ouch2.read(iprot);
+          struct.setOuch2IsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.ouch3 = new NamespaceNotFoundException();
+          struct.ouch3.read(iprot);
+          struct.setOuch3IsSet(true);
+        }
+      }
+    }
+
+  }
+
 }
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloSecurityException.java b/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloSecurityException.java
index 28b1e6c..f77a908 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloSecurityException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloSecurityException.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class AccumuloSecurityException extends TException implements org.apache.thrift.TBase<AccumuloSecurityException, AccumuloSecurityException._Fields>, java.io.Serializable, Cloneable, Comparable<AccumuloSecurityException> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class AccumuloSecurityException extends TException implements org.apache.thrift.TBase<AccumuloSecurityException, AccumuloSecurityException._Fields>, java.io.Serializable, Cloneable, Comparable<AccumuloSecurityException> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("AccumuloSecurityException");
 
   private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -243,7 +246,14 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ActiveCompaction.java b/src/main/java/org/apache/accumulo/proxy/thrift/ActiveCompaction.java
index 58e1321..986b68c 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ActiveCompaction.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ActiveCompaction.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class ActiveCompaction implements org.apache.thrift.TBase<ActiveCompaction, ActiveCompaction._Fields>, java.io.Serializable, Cloneable, Comparable<ActiveCompaction> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class ActiveCompaction implements org.apache.thrift.TBase<ActiveCompaction, ActiveCompaction._Fields>, java.io.Serializable, Cloneable, Comparable<ActiveCompaction> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ActiveCompaction");
 
   private static final org.apache.thrift.protocol.TField EXTENT_FIELD_DESC = new org.apache.thrift.protocol.TField("extent", org.apache.thrift.protocol.TType.STRUCT, (short)1);
@@ -676,7 +679,7 @@
       return getExtent();
 
     case AGE:
-      return Long.valueOf(getAge());
+      return getAge();
 
     case INPUT_FILES:
       return getInputFiles();
@@ -694,10 +697,10 @@
       return getLocalityGroup();
 
     case ENTRIES_READ:
-      return Long.valueOf(getEntriesRead());
+      return getEntriesRead();
 
     case ENTRIES_WRITTEN:
-      return Long.valueOf(getEntriesWritten());
+      return getEntriesWritten();
 
     case ITERATORS:
       return getIterators();
@@ -845,7 +848,59 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_extent = true && (isSetExtent());
+    list.add(present_extent);
+    if (present_extent)
+      list.add(extent);
+
+    boolean present_age = true;
+    list.add(present_age);
+    if (present_age)
+      list.add(age);
+
+    boolean present_inputFiles = true && (isSetInputFiles());
+    list.add(present_inputFiles);
+    if (present_inputFiles)
+      list.add(inputFiles);
+
+    boolean present_outputFile = true && (isSetOutputFile());
+    list.add(present_outputFile);
+    if (present_outputFile)
+      list.add(outputFile);
+
+    boolean present_type = true && (isSetType());
+    list.add(present_type);
+    if (present_type)
+      list.add(type.getValue());
+
+    boolean present_reason = true && (isSetReason());
+    list.add(present_reason);
+    if (present_reason)
+      list.add(reason.getValue());
+
+    boolean present_localityGroup = true && (isSetLocalityGroup());
+    list.add(present_localityGroup);
+    if (present_localityGroup)
+      list.add(localityGroup);
+
+    boolean present_entriesRead = true;
+    list.add(present_entriesRead);
+    if (present_entriesRead)
+      list.add(entriesRead);
+
+    boolean present_entriesWritten = true;
+    list.add(present_entriesWritten);
+    if (present_entriesWritten)
+      list.add(entriesWritten);
+
+    boolean present_iterators = true && (isSetIterators());
+    list.add(present_iterators);
+    if (present_iterators)
+      list.add(iterators);
+
+    return list.hashCode();
   }
 
   @Override
@@ -1113,11 +1168,11 @@
               {
                 org.apache.thrift.protocol.TList _list138 = iprot.readListBegin();
                 struct.inputFiles = new ArrayList<String>(_list138.size);
-                for (int _i139 = 0; _i139 < _list138.size; ++_i139)
+                String _elem139;
+                for (int _i140 = 0; _i140 < _list138.size; ++_i140)
                 {
-                  String _elem140;
-                  _elem140 = iprot.readString();
-                  struct.inputFiles.add(_elem140);
+                  _elem139 = iprot.readString();
+                  struct.inputFiles.add(_elem139);
                 }
                 iprot.readListEnd();
               }
@@ -1136,7 +1191,7 @@
             break;
           case 5: // TYPE
             if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-              struct.type = CompactionType.findByValue(iprot.readI32());
+              struct.type = org.apache.accumulo.proxy.thrift.CompactionType.findByValue(iprot.readI32());
               struct.setTypeIsSet(true);
             } else { 
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -1144,7 +1199,7 @@
             break;
           case 6: // REASON
             if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-              struct.reason = CompactionReason.findByValue(iprot.readI32());
+              struct.reason = org.apache.accumulo.proxy.thrift.CompactionReason.findByValue(iprot.readI32());
               struct.setReasonIsSet(true);
             } else { 
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -1179,12 +1234,12 @@
               {
                 org.apache.thrift.protocol.TList _list141 = iprot.readListBegin();
                 struct.iterators = new ArrayList<IteratorSetting>(_list141.size);
-                for (int _i142 = 0; _i142 < _list141.size; ++_i142)
+                IteratorSetting _elem142;
+                for (int _i143 = 0; _i143 < _list141.size; ++_i143)
                 {
-                  IteratorSetting _elem143;
-                  _elem143 = new IteratorSetting();
-                  _elem143.read(iprot);
-                  struct.iterators.add(_elem143);
+                  _elem142 = new IteratorSetting();
+                  _elem142.read(iprot);
+                  struct.iterators.add(_elem142);
                 }
                 iprot.readListEnd();
               }
@@ -1376,11 +1431,11 @@
         {
           org.apache.thrift.protocol.TList _list148 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
           struct.inputFiles = new ArrayList<String>(_list148.size);
-          for (int _i149 = 0; _i149 < _list148.size; ++_i149)
+          String _elem149;
+          for (int _i150 = 0; _i150 < _list148.size; ++_i150)
           {
-            String _elem150;
-            _elem150 = iprot.readString();
-            struct.inputFiles.add(_elem150);
+            _elem149 = iprot.readString();
+            struct.inputFiles.add(_elem149);
           }
         }
         struct.setInputFilesIsSet(true);
@@ -1390,11 +1445,11 @@
         struct.setOutputFileIsSet(true);
       }
       if (incoming.get(4)) {
-        struct.type = CompactionType.findByValue(iprot.readI32());
+        struct.type = org.apache.accumulo.proxy.thrift.CompactionType.findByValue(iprot.readI32());
         struct.setTypeIsSet(true);
       }
       if (incoming.get(5)) {
-        struct.reason = CompactionReason.findByValue(iprot.readI32());
+        struct.reason = org.apache.accumulo.proxy.thrift.CompactionReason.findByValue(iprot.readI32());
         struct.setReasonIsSet(true);
       }
       if (incoming.get(6)) {
@@ -1413,12 +1468,12 @@
         {
           org.apache.thrift.protocol.TList _list151 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.iterators = new ArrayList<IteratorSetting>(_list151.size);
-          for (int _i152 = 0; _i152 < _list151.size; ++_i152)
+          IteratorSetting _elem152;
+          for (int _i153 = 0; _i153 < _list151.size; ++_i153)
           {
-            IteratorSetting _elem153;
-            _elem153 = new IteratorSetting();
-            _elem153.read(iprot);
-            struct.iterators.add(_elem153);
+            _elem152 = new IteratorSetting();
+            _elem152.read(iprot);
+            struct.iterators.add(_elem152);
           }
         }
         struct.setIteratorsIsSet(true);
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ActiveScan.java b/src/main/java/org/apache/accumulo/proxy/thrift/ActiveScan.java
index bc9ad51..9f4d892 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ActiveScan.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ActiveScan.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class ActiveScan implements org.apache.thrift.TBase<ActiveScan, ActiveScan._Fields>, java.io.Serializable, Cloneable, Comparable<ActiveScan> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class ActiveScan implements org.apache.thrift.TBase<ActiveScan, ActiveScan._Fields>, java.io.Serializable, Cloneable, Comparable<ActiveScan> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ActiveScan");
 
   private static final org.apache.thrift.protocol.TField CLIENT_FIELD_DESC = new org.apache.thrift.protocol.TField("client", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -747,10 +750,10 @@
       return getTable();
 
     case AGE:
-      return Long.valueOf(getAge());
+      return getAge();
 
     case IDLE_TIME:
-      return Long.valueOf(getIdleTime());
+      return getIdleTime();
 
     case TYPE:
       return getType();
@@ -924,7 +927,64 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_client = true && (isSetClient());
+    list.add(present_client);
+    if (present_client)
+      list.add(client);
+
+    boolean present_user = true && (isSetUser());
+    list.add(present_user);
+    if (present_user)
+      list.add(user);
+
+    boolean present_table = true && (isSetTable());
+    list.add(present_table);
+    if (present_table)
+      list.add(table);
+
+    boolean present_age = true;
+    list.add(present_age);
+    if (present_age)
+      list.add(age);
+
+    boolean present_idleTime = true;
+    list.add(present_idleTime);
+    if (present_idleTime)
+      list.add(idleTime);
+
+    boolean present_type = true && (isSetType());
+    list.add(present_type);
+    if (present_type)
+      list.add(type.getValue());
+
+    boolean present_state = true && (isSetState());
+    list.add(present_state);
+    if (present_state)
+      list.add(state.getValue());
+
+    boolean present_extent = true && (isSetExtent());
+    list.add(present_extent);
+    if (present_extent)
+      list.add(extent);
+
+    boolean present_columns = true && (isSetColumns());
+    list.add(present_columns);
+    if (present_columns)
+      list.add(columns);
+
+    boolean present_iterators = true && (isSetIterators());
+    list.add(present_iterators);
+    if (present_iterators)
+      list.add(iterators);
+
+    boolean present_authorizations = true && (isSetAuthorizations());
+    list.add(present_authorizations);
+    if (present_authorizations)
+      list.add(authorizations);
+
+    return list.hashCode();
   }
 
   @Override
@@ -1141,7 +1201,7 @@
     if (this.authorizations == null) {
       sb.append("null");
     } else {
-      sb.append(this.authorizations);
+      org.apache.thrift.TBaseHelper.toString(this.authorizations, sb);
     }
     first = false;
     sb.append(")");
@@ -1234,7 +1294,7 @@
             break;
           case 6: // TYPE
             if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-              struct.type = ScanType.findByValue(iprot.readI32());
+              struct.type = org.apache.accumulo.proxy.thrift.ScanType.findByValue(iprot.readI32());
               struct.setTypeIsSet(true);
             } else { 
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -1242,7 +1302,7 @@
             break;
           case 7: // STATE
             if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-              struct.state = ScanState.findByValue(iprot.readI32());
+              struct.state = org.apache.accumulo.proxy.thrift.ScanState.findByValue(iprot.readI32());
               struct.setStateIsSet(true);
             } else { 
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -1262,12 +1322,12 @@
               {
                 org.apache.thrift.protocol.TList _list114 = iprot.readListBegin();
                 struct.columns = new ArrayList<Column>(_list114.size);
-                for (int _i115 = 0; _i115 < _list114.size; ++_i115)
+                Column _elem115;
+                for (int _i116 = 0; _i116 < _list114.size; ++_i116)
                 {
-                  Column _elem116;
-                  _elem116 = new Column();
-                  _elem116.read(iprot);
-                  struct.columns.add(_elem116);
+                  _elem115 = new Column();
+                  _elem115.read(iprot);
+                  struct.columns.add(_elem115);
                 }
                 iprot.readListEnd();
               }
@@ -1281,12 +1341,12 @@
               {
                 org.apache.thrift.protocol.TList _list117 = iprot.readListBegin();
                 struct.iterators = new ArrayList<IteratorSetting>(_list117.size);
-                for (int _i118 = 0; _i118 < _list117.size; ++_i118)
+                IteratorSetting _elem118;
+                for (int _i119 = 0; _i119 < _list117.size; ++_i119)
                 {
-                  IteratorSetting _elem119;
-                  _elem119 = new IteratorSetting();
-                  _elem119.read(iprot);
-                  struct.iterators.add(_elem119);
+                  _elem118 = new IteratorSetting();
+                  _elem118.read(iprot);
+                  struct.iterators.add(_elem118);
                 }
                 iprot.readListEnd();
               }
@@ -1300,11 +1360,11 @@
               {
                 org.apache.thrift.protocol.TList _list120 = iprot.readListBegin();
                 struct.authorizations = new ArrayList<ByteBuffer>(_list120.size);
-                for (int _i121 = 0; _i121 < _list120.size; ++_i121)
+                ByteBuffer _elem121;
+                for (int _i122 = 0; _i122 < _list120.size; ++_i122)
                 {
-                  ByteBuffer _elem122;
-                  _elem122 = iprot.readBinary();
-                  struct.authorizations.add(_elem122);
+                  _elem121 = iprot.readBinary();
+                  struct.authorizations.add(_elem121);
                 }
                 iprot.readListEnd();
               }
@@ -1530,11 +1590,11 @@
         struct.setIdleTimeIsSet(true);
       }
       if (incoming.get(5)) {
-        struct.type = ScanType.findByValue(iprot.readI32());
+        struct.type = org.apache.accumulo.proxy.thrift.ScanType.findByValue(iprot.readI32());
         struct.setTypeIsSet(true);
       }
       if (incoming.get(6)) {
-        struct.state = ScanState.findByValue(iprot.readI32());
+        struct.state = org.apache.accumulo.proxy.thrift.ScanState.findByValue(iprot.readI32());
         struct.setStateIsSet(true);
       }
       if (incoming.get(7)) {
@@ -1546,12 +1606,12 @@
         {
           org.apache.thrift.protocol.TList _list129 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.columns = new ArrayList<Column>(_list129.size);
-          for (int _i130 = 0; _i130 < _list129.size; ++_i130)
+          Column _elem130;
+          for (int _i131 = 0; _i131 < _list129.size; ++_i131)
           {
-            Column _elem131;
-            _elem131 = new Column();
-            _elem131.read(iprot);
-            struct.columns.add(_elem131);
+            _elem130 = new Column();
+            _elem130.read(iprot);
+            struct.columns.add(_elem130);
           }
         }
         struct.setColumnsIsSet(true);
@@ -1560,12 +1620,12 @@
         {
           org.apache.thrift.protocol.TList _list132 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.iterators = new ArrayList<IteratorSetting>(_list132.size);
-          for (int _i133 = 0; _i133 < _list132.size; ++_i133)
+          IteratorSetting _elem133;
+          for (int _i134 = 0; _i134 < _list132.size; ++_i134)
           {
-            IteratorSetting _elem134;
-            _elem134 = new IteratorSetting();
-            _elem134.read(iprot);
-            struct.iterators.add(_elem134);
+            _elem133 = new IteratorSetting();
+            _elem133.read(iprot);
+            struct.iterators.add(_elem133);
           }
         }
         struct.setIteratorsIsSet(true);
@@ -1574,11 +1634,11 @@
         {
           org.apache.thrift.protocol.TList _list135 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
           struct.authorizations = new ArrayList<ByteBuffer>(_list135.size);
-          for (int _i136 = 0; _i136 < _list135.size; ++_i136)
+          ByteBuffer _elem136;
+          for (int _i137 = 0; _i137 < _list135.size; ++_i137)
           {
-            ByteBuffer _elem137;
-            _elem137 = iprot.readBinary();
-            struct.authorizations.add(_elem137);
+            _elem136 = iprot.readBinary();
+            struct.authorizations.add(_elem136);
           }
         }
         struct.setAuthorizationsIsSet(true);
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/BatchScanOptions.java b/src/main/java/org/apache/accumulo/proxy/thrift/BatchScanOptions.java
index 948d822..777e075 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/BatchScanOptions.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/BatchScanOptions.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class BatchScanOptions implements org.apache.thrift.TBase<BatchScanOptions, BatchScanOptions._Fields>, java.io.Serializable, Cloneable, Comparable<BatchScanOptions> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class BatchScanOptions implements org.apache.thrift.TBase<BatchScanOptions, BatchScanOptions._Fields>, java.io.Serializable, Cloneable, Comparable<BatchScanOptions> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("BatchScanOptions");
 
   private static final org.apache.thrift.protocol.TField AUTHORIZATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("authorizations", org.apache.thrift.protocol.TType.SET, (short)1);
@@ -142,7 +145,7 @@
   // isset id assignments
   private static final int __THREADS_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
-  private _Fields optionals[] = {_Fields.AUTHORIZATIONS,_Fields.RANGES,_Fields.COLUMNS,_Fields.ITERATORS,_Fields.THREADS};
+  private static final _Fields optionals[] = {_Fields.AUTHORIZATIONS,_Fields.RANGES,_Fields.COLUMNS,_Fields.ITERATORS,_Fields.THREADS};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
@@ -453,7 +456,7 @@
       return getIterators();
 
     case THREADS:
-      return Integer.valueOf(getThreads());
+      return getThreads();
 
     }
     throw new IllegalStateException();
@@ -543,7 +546,34 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_authorizations = true && (isSetAuthorizations());
+    list.add(present_authorizations);
+    if (present_authorizations)
+      list.add(authorizations);
+
+    boolean present_ranges = true && (isSetRanges());
+    list.add(present_ranges);
+    if (present_ranges)
+      list.add(ranges);
+
+    boolean present_columns = true && (isSetColumns());
+    list.add(present_columns);
+    if (present_columns)
+      list.add(columns);
+
+    boolean present_iterators = true && (isSetIterators());
+    list.add(present_iterators);
+    if (present_iterators)
+      list.add(iterators);
+
+    boolean present_threads = true && (isSetThreads());
+    list.add(present_threads);
+    if (present_threads)
+      list.add(threads);
+
+    return list.hashCode();
   }
 
   @Override
@@ -629,7 +659,7 @@
       if (this.authorizations == null) {
         sb.append("null");
       } else {
-        sb.append(this.authorizations);
+        org.apache.thrift.TBaseHelper.toString(this.authorizations, sb);
       }
       first = false;
     }
@@ -719,11 +749,11 @@
               {
                 org.apache.thrift.protocol.TSet _set50 = iprot.readSetBegin();
                 struct.authorizations = new HashSet<ByteBuffer>(2*_set50.size);
-                for (int _i51 = 0; _i51 < _set50.size; ++_i51)
+                ByteBuffer _elem51;
+                for (int _i52 = 0; _i52 < _set50.size; ++_i52)
                 {
-                  ByteBuffer _elem52;
-                  _elem52 = iprot.readBinary();
-                  struct.authorizations.add(_elem52);
+                  _elem51 = iprot.readBinary();
+                  struct.authorizations.add(_elem51);
                 }
                 iprot.readSetEnd();
               }
@@ -737,12 +767,12 @@
               {
                 org.apache.thrift.protocol.TList _list53 = iprot.readListBegin();
                 struct.ranges = new ArrayList<Range>(_list53.size);
-                for (int _i54 = 0; _i54 < _list53.size; ++_i54)
+                Range _elem54;
+                for (int _i55 = 0; _i55 < _list53.size; ++_i55)
                 {
-                  Range _elem55;
-                  _elem55 = new Range();
-                  _elem55.read(iprot);
-                  struct.ranges.add(_elem55);
+                  _elem54 = new Range();
+                  _elem54.read(iprot);
+                  struct.ranges.add(_elem54);
                 }
                 iprot.readListEnd();
               }
@@ -756,12 +786,12 @@
               {
                 org.apache.thrift.protocol.TList _list56 = iprot.readListBegin();
                 struct.columns = new ArrayList<ScanColumn>(_list56.size);
-                for (int _i57 = 0; _i57 < _list56.size; ++_i57)
+                ScanColumn _elem57;
+                for (int _i58 = 0; _i58 < _list56.size; ++_i58)
                 {
-                  ScanColumn _elem58;
-                  _elem58 = new ScanColumn();
-                  _elem58.read(iprot);
-                  struct.columns.add(_elem58);
+                  _elem57 = new ScanColumn();
+                  _elem57.read(iprot);
+                  struct.columns.add(_elem57);
                 }
                 iprot.readListEnd();
               }
@@ -775,12 +805,12 @@
               {
                 org.apache.thrift.protocol.TList _list59 = iprot.readListBegin();
                 struct.iterators = new ArrayList<IteratorSetting>(_list59.size);
-                for (int _i60 = 0; _i60 < _list59.size; ++_i60)
+                IteratorSetting _elem60;
+                for (int _i61 = 0; _i61 < _list59.size; ++_i61)
                 {
-                  IteratorSetting _elem61;
-                  _elem61 = new IteratorSetting();
-                  _elem61.read(iprot);
-                  struct.iterators.add(_elem61);
+                  _elem60 = new IteratorSetting();
+                  _elem60.read(iprot);
+                  struct.iterators.add(_elem60);
                 }
                 iprot.readListEnd();
               }
@@ -956,11 +986,11 @@
         {
           org.apache.thrift.protocol.TSet _set70 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
           struct.authorizations = new HashSet<ByteBuffer>(2*_set70.size);
-          for (int _i71 = 0; _i71 < _set70.size; ++_i71)
+          ByteBuffer _elem71;
+          for (int _i72 = 0; _i72 < _set70.size; ++_i72)
           {
-            ByteBuffer _elem72;
-            _elem72 = iprot.readBinary();
-            struct.authorizations.add(_elem72);
+            _elem71 = iprot.readBinary();
+            struct.authorizations.add(_elem71);
           }
         }
         struct.setAuthorizationsIsSet(true);
@@ -969,12 +999,12 @@
         {
           org.apache.thrift.protocol.TList _list73 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.ranges = new ArrayList<Range>(_list73.size);
-          for (int _i74 = 0; _i74 < _list73.size; ++_i74)
+          Range _elem74;
+          for (int _i75 = 0; _i75 < _list73.size; ++_i75)
           {
-            Range _elem75;
-            _elem75 = new Range();
-            _elem75.read(iprot);
-            struct.ranges.add(_elem75);
+            _elem74 = new Range();
+            _elem74.read(iprot);
+            struct.ranges.add(_elem74);
           }
         }
         struct.setRangesIsSet(true);
@@ -983,12 +1013,12 @@
         {
           org.apache.thrift.protocol.TList _list76 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.columns = new ArrayList<ScanColumn>(_list76.size);
-          for (int _i77 = 0; _i77 < _list76.size; ++_i77)
+          ScanColumn _elem77;
+          for (int _i78 = 0; _i78 < _list76.size; ++_i78)
           {
-            ScanColumn _elem78;
-            _elem78 = new ScanColumn();
-            _elem78.read(iprot);
-            struct.columns.add(_elem78);
+            _elem77 = new ScanColumn();
+            _elem77.read(iprot);
+            struct.columns.add(_elem77);
           }
         }
         struct.setColumnsIsSet(true);
@@ -997,12 +1027,12 @@
         {
           org.apache.thrift.protocol.TList _list79 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.iterators = new ArrayList<IteratorSetting>(_list79.size);
-          for (int _i80 = 0; _i80 < _list79.size; ++_i80)
+          IteratorSetting _elem80;
+          for (int _i81 = 0; _i81 < _list79.size; ++_i81)
           {
-            IteratorSetting _elem81;
-            _elem81 = new IteratorSetting();
-            _elem81.read(iprot);
-            struct.iterators.add(_elem81);
+            _elem80 = new IteratorSetting();
+            _elem80.read(iprot);
+            struct.iterators.add(_elem80);
           }
         }
         struct.setIteratorsIsSet(true);
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/Column.java b/src/main/java/org/apache/accumulo/proxy/thrift/Column.java
index 007eb53..96ae162 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/Column.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/Column.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class Column implements org.apache.thrift.TBase<Column, Column._Fields>, java.io.Serializable, Cloneable, Comparable<Column> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class Column implements org.apache.thrift.TBase<Column, Column._Fields>, java.io.Serializable, Cloneable, Comparable<Column> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Column");
 
   private static final org.apache.thrift.protocol.TField COL_FAMILY_FIELD_DESC = new org.apache.thrift.protocol.TField("colFamily", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -152,9 +155,9 @@
     ByteBuffer colVisibility)
   {
     this();
-    this.colFamily = colFamily;
-    this.colQualifier = colQualifier;
-    this.colVisibility = colVisibility;
+    this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
+    this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
+    this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
   }
 
   /**
@@ -163,15 +166,12 @@
   public Column(Column other) {
     if (other.isSetColFamily()) {
       this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(other.colFamily);
-;
     }
     if (other.isSetColQualifier()) {
       this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(other.colQualifier);
-;
     }
     if (other.isSetColVisibility()) {
       this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(other.colVisibility);
-;
     }
   }
 
@@ -192,16 +192,16 @@
   }
 
   public ByteBuffer bufferForColFamily() {
-    return colFamily;
+    return org.apache.thrift.TBaseHelper.copyBinary(colFamily);
   }
 
   public Column setColFamily(byte[] colFamily) {
-    setColFamily(colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(colFamily));
+    this.colFamily = colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colFamily, colFamily.length));
     return this;
   }
 
   public Column setColFamily(ByteBuffer colFamily) {
-    this.colFamily = colFamily;
+    this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
     return this;
   }
 
@@ -226,16 +226,16 @@
   }
 
   public ByteBuffer bufferForColQualifier() {
-    return colQualifier;
+    return org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
   }
 
   public Column setColQualifier(byte[] colQualifier) {
-    setColQualifier(colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(colQualifier));
+    this.colQualifier = colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colQualifier, colQualifier.length));
     return this;
   }
 
   public Column setColQualifier(ByteBuffer colQualifier) {
-    this.colQualifier = colQualifier;
+    this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
     return this;
   }
 
@@ -260,16 +260,16 @@
   }
 
   public ByteBuffer bufferForColVisibility() {
-    return colVisibility;
+    return org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
   }
 
   public Column setColVisibility(byte[] colVisibility) {
-    setColVisibility(colVisibility == null ? (ByteBuffer)null : ByteBuffer.wrap(colVisibility));
+    this.colVisibility = colVisibility == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colVisibility, colVisibility.length));
     return this;
   }
 
   public Column setColVisibility(ByteBuffer colVisibility) {
-    this.colVisibility = colVisibility;
+    this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
     return this;
   }
 
@@ -394,7 +394,24 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_colFamily = true && (isSetColFamily());
+    list.add(present_colFamily);
+    if (present_colFamily)
+      list.add(colFamily);
+
+    boolean present_colQualifier = true && (isSetColQualifier());
+    list.add(present_colQualifier);
+    if (present_colQualifier)
+      list.add(colQualifier);
+
+    boolean present_colVisibility = true && (isSetColVisibility());
+    list.add(present_colVisibility);
+    if (present_colVisibility)
+      list.add(colVisibility);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ColumnUpdate.java b/src/main/java/org/apache/accumulo/proxy/thrift/ColumnUpdate.java
index 97d9542..33dfdbe 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ColumnUpdate.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ColumnUpdate.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class ColumnUpdate implements org.apache.thrift.TBase<ColumnUpdate, ColumnUpdate._Fields>, java.io.Serializable, Cloneable, Comparable<ColumnUpdate> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class ColumnUpdate implements org.apache.thrift.TBase<ColumnUpdate, ColumnUpdate._Fields>, java.io.Serializable, Cloneable, Comparable<ColumnUpdate> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ColumnUpdate");
 
   private static final org.apache.thrift.protocol.TField COL_FAMILY_FIELD_DESC = new org.apache.thrift.protocol.TField("colFamily", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -148,7 +151,7 @@
   private static final int __TIMESTAMP_ISSET_ID = 0;
   private static final int __DELETECELL_ISSET_ID = 1;
   private byte __isset_bitfield = 0;
-  private _Fields optionals[] = {_Fields.COL_VISIBILITY,_Fields.TIMESTAMP,_Fields.VALUE,_Fields.DELETE_CELL};
+  private static final _Fields optionals[] = {_Fields.COL_VISIBILITY,_Fields.TIMESTAMP,_Fields.VALUE,_Fields.DELETE_CELL};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
@@ -176,8 +179,8 @@
     ByteBuffer colQualifier)
   {
     this();
-    this.colFamily = colFamily;
-    this.colQualifier = colQualifier;
+    this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
+    this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
   }
 
   /**
@@ -187,20 +190,16 @@
     __isset_bitfield = other.__isset_bitfield;
     if (other.isSetColFamily()) {
       this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(other.colFamily);
-;
     }
     if (other.isSetColQualifier()) {
       this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(other.colQualifier);
-;
     }
     if (other.isSetColVisibility()) {
       this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(other.colVisibility);
-;
     }
     this.timestamp = other.timestamp;
     if (other.isSetValue()) {
       this.value = org.apache.thrift.TBaseHelper.copyBinary(other.value);
-;
     }
     this.deleteCell = other.deleteCell;
   }
@@ -227,16 +226,16 @@
   }
 
   public ByteBuffer bufferForColFamily() {
-    return colFamily;
+    return org.apache.thrift.TBaseHelper.copyBinary(colFamily);
   }
 
   public ColumnUpdate setColFamily(byte[] colFamily) {
-    setColFamily(colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(colFamily));
+    this.colFamily = colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colFamily, colFamily.length));
     return this;
   }
 
   public ColumnUpdate setColFamily(ByteBuffer colFamily) {
-    this.colFamily = colFamily;
+    this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
     return this;
   }
 
@@ -261,16 +260,16 @@
   }
 
   public ByteBuffer bufferForColQualifier() {
-    return colQualifier;
+    return org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
   }
 
   public ColumnUpdate setColQualifier(byte[] colQualifier) {
-    setColQualifier(colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(colQualifier));
+    this.colQualifier = colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colQualifier, colQualifier.length));
     return this;
   }
 
   public ColumnUpdate setColQualifier(ByteBuffer colQualifier) {
-    this.colQualifier = colQualifier;
+    this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
     return this;
   }
 
@@ -295,16 +294,16 @@
   }
 
   public ByteBuffer bufferForColVisibility() {
-    return colVisibility;
+    return org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
   }
 
   public ColumnUpdate setColVisibility(byte[] colVisibility) {
-    setColVisibility(colVisibility == null ? (ByteBuffer)null : ByteBuffer.wrap(colVisibility));
+    this.colVisibility = colVisibility == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colVisibility, colVisibility.length));
     return this;
   }
 
   public ColumnUpdate setColVisibility(ByteBuffer colVisibility) {
-    this.colVisibility = colVisibility;
+    this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
     return this;
   }
 
@@ -352,16 +351,16 @@
   }
 
   public ByteBuffer bufferForValue() {
-    return value;
+    return org.apache.thrift.TBaseHelper.copyBinary(value);
   }
 
   public ColumnUpdate setValue(byte[] value) {
-    setValue(value == null ? (ByteBuffer)null : ByteBuffer.wrap(value));
+    this.value = value == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(value, value.length));
     return this;
   }
 
   public ColumnUpdate setValue(ByteBuffer value) {
-    this.value = value;
+    this.value = org.apache.thrift.TBaseHelper.copyBinary(value);
     return this;
   }
 
@@ -468,13 +467,13 @@
       return getColVisibility();
 
     case TIMESTAMP:
-      return Long.valueOf(getTimestamp());
+      return getTimestamp();
 
     case VALUE:
       return getValue();
 
     case DELETE_CELL:
-      return Boolean.valueOf(isDeleteCell());
+      return isDeleteCell();
 
     }
     throw new IllegalStateException();
@@ -575,7 +574,39 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_colFamily = true && (isSetColFamily());
+    list.add(present_colFamily);
+    if (present_colFamily)
+      list.add(colFamily);
+
+    boolean present_colQualifier = true && (isSetColQualifier());
+    list.add(present_colQualifier);
+    if (present_colQualifier)
+      list.add(colQualifier);
+
+    boolean present_colVisibility = true && (isSetColVisibility());
+    list.add(present_colVisibility);
+    if (present_colVisibility)
+      list.add(colVisibility);
+
+    boolean present_timestamp = true && (isSetTimestamp());
+    list.add(present_timestamp);
+    if (present_timestamp)
+      list.add(timestamp);
+
+    boolean present_value = true && (isSetValue());
+    list.add(present_value);
+    if (present_value)
+      list.add(value);
+
+    boolean present_deleteCell = true && (isSetDeleteCell());
+    list.add(present_deleteCell);
+    if (present_deleteCell)
+      list.add(deleteCell);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/CompactionReason.java b/src/main/java/org/apache/accumulo/proxy/thrift/CompactionReason.java
index 1875275..77cf53d 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/CompactionReason.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/CompactionReason.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/CompactionStrategyConfig.java b/src/main/java/org/apache/accumulo/proxy/thrift/CompactionStrategyConfig.java
index 2e74e39..e8f7f88 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/CompactionStrategyConfig.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/CompactionStrategyConfig.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class CompactionStrategyConfig implements org.apache.thrift.TBase<CompactionStrategyConfig, CompactionStrategyConfig._Fields>, java.io.Serializable, Cloneable, Comparable<CompactionStrategyConfig> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class CompactionStrategyConfig implements org.apache.thrift.TBase<CompactionStrategyConfig, CompactionStrategyConfig._Fields>, java.io.Serializable, Cloneable, Comparable<CompactionStrategyConfig> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("CompactionStrategyConfig");
 
   private static final org.apache.thrift.protocol.TField CLASS_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("className", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -316,7 +319,19 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_className = true && (isSetClassName());
+    list.add(present_className);
+    if (present_className)
+      list.add(className);
+
+    boolean present_options = true && (isSetOptions());
+    list.add(present_options);
+    if (present_options)
+      list.add(options);
+
+    return list.hashCode();
   }
 
   @Override
@@ -438,13 +453,13 @@
               {
                 org.apache.thrift.protocol.TMap _map154 = iprot.readMapBegin();
                 struct.options = new HashMap<String,String>(2*_map154.size);
-                for (int _i155 = 0; _i155 < _map154.size; ++_i155)
+                String _key155;
+                String _val156;
+                for (int _i157 = 0; _i157 < _map154.size; ++_i157)
                 {
-                  String _key156;
-                  String _val157;
-                  _key156 = iprot.readString();
-                  _val157 = iprot.readString();
-                  struct.options.put(_key156, _val157);
+                  _key155 = iprot.readString();
+                  _val156 = iprot.readString();
+                  struct.options.put(_key155, _val156);
                 }
                 iprot.readMapEnd();
               }
@@ -538,13 +553,13 @@
         {
           org.apache.thrift.protocol.TMap _map160 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
           struct.options = new HashMap<String,String>(2*_map160.size);
-          for (int _i161 = 0; _i161 < _map160.size; ++_i161)
+          String _key161;
+          String _val162;
+          for (int _i163 = 0; _i163 < _map160.size; ++_i163)
           {
-            String _key162;
-            String _val163;
-            _key162 = iprot.readString();
-            _val163 = iprot.readString();
-            struct.options.put(_key162, _val163);
+            _key161 = iprot.readString();
+            _val162 = iprot.readString();
+            struct.options.put(_key161, _val162);
           }
         }
         struct.setOptionsIsSet(true);
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/CompactionType.java b/src/main/java/org/apache/accumulo/proxy/thrift/CompactionType.java
index 1b82951..d561796 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/CompactionType.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/CompactionType.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/Condition.java b/src/main/java/org/apache/accumulo/proxy/thrift/Condition.java
index c4b3c07..d946a87 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/Condition.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/Condition.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class Condition implements org.apache.thrift.TBase<Condition, Condition._Fields>, java.io.Serializable, Cloneable, Comparable<Condition> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class Condition implements org.apache.thrift.TBase<Condition, Condition._Fields>, java.io.Serializable, Cloneable, Comparable<Condition> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Condition");
 
   private static final org.apache.thrift.protocol.TField COLUMN_FIELD_DESC = new org.apache.thrift.protocol.TField("column", org.apache.thrift.protocol.TType.STRUCT, (short)1);
@@ -137,7 +140,7 @@
   // isset id assignments
   private static final int __TIMESTAMP_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
-  private _Fields optionals[] = {_Fields.TIMESTAMP,_Fields.VALUE,_Fields.ITERATORS};
+  private static final _Fields optionals[] = {_Fields.TIMESTAMP,_Fields.VALUE,_Fields.ITERATORS};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
@@ -175,7 +178,6 @@
     this.timestamp = other.timestamp;
     if (other.isSetValue()) {
       this.value = org.apache.thrift.TBaseHelper.copyBinary(other.value);
-;
     }
     if (other.isSetIterators()) {
       List<IteratorSetting> __this__iterators = new ArrayList<IteratorSetting>(other.iterators.size());
@@ -252,16 +254,16 @@
   }
 
   public ByteBuffer bufferForValue() {
-    return value;
+    return org.apache.thrift.TBaseHelper.copyBinary(value);
   }
 
   public Condition setValue(byte[] value) {
-    setValue(value == null ? (ByteBuffer)null : ByteBuffer.wrap(value));
+    this.value = value == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(value, value.length));
     return this;
   }
 
   public Condition setValue(ByteBuffer value) {
-    this.value = value;
+    this.value = org.apache.thrift.TBaseHelper.copyBinary(value);
     return this;
   }
 
@@ -362,7 +364,7 @@
       return getColumn();
 
     case TIMESTAMP:
-      return Long.valueOf(getTimestamp());
+      return getTimestamp();
 
     case VALUE:
       return getValue();
@@ -447,7 +449,29 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_column = true && (isSetColumn());
+    list.add(present_column);
+    if (present_column)
+      list.add(column);
+
+    boolean present_timestamp = true && (isSetTimestamp());
+    list.add(present_timestamp);
+    if (present_timestamp)
+      list.add(timestamp);
+
+    boolean present_value = true && (isSetValue());
+    list.add(present_value);
+    if (present_value)
+      list.add(value);
+
+    boolean present_iterators = true && (isSetIterators());
+    list.add(present_iterators);
+    if (present_iterators)
+      list.add(iterators);
+
+    return list.hashCode();
   }
 
   @Override
@@ -629,12 +653,12 @@
               {
                 org.apache.thrift.protocol.TList _list82 = iprot.readListBegin();
                 struct.iterators = new ArrayList<IteratorSetting>(_list82.size);
-                for (int _i83 = 0; _i83 < _list82.size; ++_i83)
+                IteratorSetting _elem83;
+                for (int _i84 = 0; _i84 < _list82.size; ++_i84)
                 {
-                  IteratorSetting _elem84;
-                  _elem84 = new IteratorSetting();
-                  _elem84.read(iprot);
-                  struct.iterators.add(_elem84);
+                  _elem83 = new IteratorSetting();
+                  _elem83.read(iprot);
+                  struct.iterators.add(_elem83);
                 }
                 iprot.readListEnd();
               }
@@ -761,12 +785,12 @@
         {
           org.apache.thrift.protocol.TList _list87 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.iterators = new ArrayList<IteratorSetting>(_list87.size);
-          for (int _i88 = 0; _i88 < _list87.size; ++_i88)
+          IteratorSetting _elem88;
+          for (int _i89 = 0; _i89 < _list87.size; ++_i89)
           {
-            IteratorSetting _elem89;
-            _elem89 = new IteratorSetting();
-            _elem89.read(iprot);
-            struct.iterators.add(_elem89);
+            _elem88 = new IteratorSetting();
+            _elem88.read(iprot);
+            struct.iterators.add(_elem88);
           }
         }
         struct.setIteratorsIsSet(true);
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalStatus.java b/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalStatus.java
index 515c416..c8626a5 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalStatus.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalStatus.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalUpdates.java b/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalUpdates.java
index 551e996..07f1338 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalUpdates.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalUpdates.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class ConditionalUpdates implements org.apache.thrift.TBase<ConditionalUpdates, ConditionalUpdates._Fields>, java.io.Serializable, Cloneable, Comparable<ConditionalUpdates> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class ConditionalUpdates implements org.apache.thrift.TBase<ConditionalUpdates, ConditionalUpdates._Fields>, java.io.Serializable, Cloneable, Comparable<ConditionalUpdates> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ConditionalUpdates");
 
   private static final org.apache.thrift.protocol.TField CONDITIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("conditions", org.apache.thrift.protocol.TType.LIST, (short)2);
@@ -342,7 +345,19 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_conditions = true && (isSetConditions());
+    list.add(present_conditions);
+    if (present_conditions)
+      list.add(conditions);
+
+    boolean present_updates = true && (isSetUpdates());
+    list.add(present_updates);
+    if (present_updates)
+      list.add(updates);
+
+    return list.hashCode();
   }
 
   @Override
@@ -456,12 +471,12 @@
               {
                 org.apache.thrift.protocol.TList _list90 = iprot.readListBegin();
                 struct.conditions = new ArrayList<Condition>(_list90.size);
-                for (int _i91 = 0; _i91 < _list90.size; ++_i91)
+                Condition _elem91;
+                for (int _i92 = 0; _i92 < _list90.size; ++_i92)
                 {
-                  Condition _elem92;
-                  _elem92 = new Condition();
-                  _elem92.read(iprot);
-                  struct.conditions.add(_elem92);
+                  _elem91 = new Condition();
+                  _elem91.read(iprot);
+                  struct.conditions.add(_elem91);
                 }
                 iprot.readListEnd();
               }
@@ -475,12 +490,12 @@
               {
                 org.apache.thrift.protocol.TList _list93 = iprot.readListBegin();
                 struct.updates = new ArrayList<ColumnUpdate>(_list93.size);
-                for (int _i94 = 0; _i94 < _list93.size; ++_i94)
+                ColumnUpdate _elem94;
+                for (int _i95 = 0; _i95 < _list93.size; ++_i95)
                 {
-                  ColumnUpdate _elem95;
-                  _elem95 = new ColumnUpdate();
-                  _elem95.read(iprot);
-                  struct.updates.add(_elem95);
+                  _elem94 = new ColumnUpdate();
+                  _elem94.read(iprot);
+                  struct.updates.add(_elem94);
                 }
                 iprot.readListEnd();
               }
@@ -581,12 +596,12 @@
         {
           org.apache.thrift.protocol.TList _list100 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.conditions = new ArrayList<Condition>(_list100.size);
-          for (int _i101 = 0; _i101 < _list100.size; ++_i101)
+          Condition _elem101;
+          for (int _i102 = 0; _i102 < _list100.size; ++_i102)
           {
-            Condition _elem102;
-            _elem102 = new Condition();
-            _elem102.read(iprot);
-            struct.conditions.add(_elem102);
+            _elem101 = new Condition();
+            _elem101.read(iprot);
+            struct.conditions.add(_elem101);
           }
         }
         struct.setConditionsIsSet(true);
@@ -595,12 +610,12 @@
         {
           org.apache.thrift.protocol.TList _list103 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.updates = new ArrayList<ColumnUpdate>(_list103.size);
-          for (int _i104 = 0; _i104 < _list103.size; ++_i104)
+          ColumnUpdate _elem104;
+          for (int _i105 = 0; _i105 < _list103.size; ++_i105)
           {
-            ColumnUpdate _elem105;
-            _elem105 = new ColumnUpdate();
-            _elem105.read(iprot);
-            struct.updates.add(_elem105);
+            _elem104 = new ColumnUpdate();
+            _elem104.read(iprot);
+            struct.updates.add(_elem104);
           }
         }
         struct.setUpdatesIsSet(true);
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalWriterOptions.java b/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalWriterOptions.java
index 16b21fc..16c78a3 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalWriterOptions.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalWriterOptions.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class ConditionalWriterOptions implements org.apache.thrift.TBase<ConditionalWriterOptions, ConditionalWriterOptions._Fields>, java.io.Serializable, Cloneable, Comparable<ConditionalWriterOptions> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class ConditionalWriterOptions implements org.apache.thrift.TBase<ConditionalWriterOptions, ConditionalWriterOptions._Fields>, java.io.Serializable, Cloneable, Comparable<ConditionalWriterOptions> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ConditionalWriterOptions");
 
   private static final org.apache.thrift.protocol.TField MAX_MEMORY_FIELD_DESC = new org.apache.thrift.protocol.TField("maxMemory", org.apache.thrift.protocol.TType.I64, (short)1);
@@ -152,7 +155,7 @@
   private static final int __TIMEOUTMS_ISSET_ID = 1;
   private static final int __THREADS_ISSET_ID = 2;
   private byte __isset_bitfield = 0;
-  private _Fields optionals[] = {_Fields.MAX_MEMORY,_Fields.TIMEOUT_MS,_Fields.THREADS,_Fields.AUTHORIZATIONS,_Fields.DURABILITY};
+  private static final _Fields optionals[] = {_Fields.MAX_MEMORY,_Fields.TIMEOUT_MS,_Fields.THREADS,_Fields.AUTHORIZATIONS,_Fields.DURABILITY};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
@@ -395,13 +398,13 @@
   public Object getFieldValue(_Fields field) {
     switch (field) {
     case MAX_MEMORY:
-      return Long.valueOf(getMaxMemory());
+      return getMaxMemory();
 
     case TIMEOUT_MS:
-      return Long.valueOf(getTimeoutMs());
+      return getTimeoutMs();
 
     case THREADS:
-      return Integer.valueOf(getThreads());
+      return getThreads();
 
     case AUTHORIZATIONS:
       return getAuthorizations();
@@ -497,7 +500,34 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_maxMemory = true && (isSetMaxMemory());
+    list.add(present_maxMemory);
+    if (present_maxMemory)
+      list.add(maxMemory);
+
+    boolean present_timeoutMs = true && (isSetTimeoutMs());
+    list.add(present_timeoutMs);
+    if (present_timeoutMs)
+      list.add(timeoutMs);
+
+    boolean present_threads = true && (isSetThreads());
+    list.add(present_threads);
+    if (present_threads)
+      list.add(threads);
+
+    boolean present_authorizations = true && (isSetAuthorizations());
+    list.add(present_authorizations);
+    if (present_authorizations)
+      list.add(authorizations);
+
+    boolean present_durability = true && (isSetDurability());
+    list.add(present_durability);
+    if (present_durability)
+      list.add(durability.getValue());
+
+    return list.hashCode();
   }
 
   @Override
@@ -601,7 +631,7 @@
       if (this.authorizations == null) {
         sb.append("null");
       } else {
-        sb.append(this.authorizations);
+        org.apache.thrift.TBaseHelper.toString(this.authorizations, sb);
       }
       first = false;
     }
@@ -689,11 +719,11 @@
               {
                 org.apache.thrift.protocol.TSet _set106 = iprot.readSetBegin();
                 struct.authorizations = new HashSet<ByteBuffer>(2*_set106.size);
-                for (int _i107 = 0; _i107 < _set106.size; ++_i107)
+                ByteBuffer _elem107;
+                for (int _i108 = 0; _i108 < _set106.size; ++_i108)
                 {
-                  ByteBuffer _elem108;
-                  _elem108 = iprot.readBinary();
-                  struct.authorizations.add(_elem108);
+                  _elem107 = iprot.readBinary();
+                  struct.authorizations.add(_elem107);
                 }
                 iprot.readSetEnd();
               }
@@ -704,7 +734,7 @@
             break;
           case 5: // DURABILITY
             if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-              struct.durability = Durability.findByValue(iprot.readI32());
+              struct.durability = org.apache.accumulo.proxy.thrift.Durability.findByValue(iprot.readI32());
               struct.setDurabilityIsSet(true);
             } else { 
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -838,17 +868,17 @@
         {
           org.apache.thrift.protocol.TSet _set111 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
           struct.authorizations = new HashSet<ByteBuffer>(2*_set111.size);
-          for (int _i112 = 0; _i112 < _set111.size; ++_i112)
+          ByteBuffer _elem112;
+          for (int _i113 = 0; _i113 < _set111.size; ++_i113)
           {
-            ByteBuffer _elem113;
-            _elem113 = iprot.readBinary();
-            struct.authorizations.add(_elem113);
+            _elem112 = iprot.readBinary();
+            struct.authorizations.add(_elem112);
           }
         }
         struct.setAuthorizationsIsSet(true);
       }
       if (incoming.get(4)) {
-        struct.durability = Durability.findByValue(iprot.readI32());
+        struct.durability = org.apache.accumulo.proxy.thrift.Durability.findByValue(iprot.readI32());
         struct.setDurabilityIsSet(true);
       }
     }
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/DiskUsage.java b/src/main/java/org/apache/accumulo/proxy/thrift/DiskUsage.java
index 82a886d..c49910f 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/DiskUsage.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/DiskUsage.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class DiskUsage implements org.apache.thrift.TBase<DiskUsage, DiskUsage._Fields>, java.io.Serializable, Cloneable, Comparable<DiskUsage> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class DiskUsage implements org.apache.thrift.TBase<DiskUsage, DiskUsage._Fields>, java.io.Serializable, Cloneable, Comparable<DiskUsage> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("DiskUsage");
 
   private static final org.apache.thrift.protocol.TField TABLES_FIELD_DESC = new org.apache.thrift.protocol.TField("tables", org.apache.thrift.protocol.TType.LIST, (short)1);
@@ -264,7 +267,7 @@
       return getTables();
 
     case USAGE:
-      return Long.valueOf(getUsage());
+      return getUsage();
 
     }
     throw new IllegalStateException();
@@ -321,7 +324,19 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_tables = true && (isSetTables());
+    list.add(present_tables);
+    if (present_tables)
+      list.add(tables);
+
+    boolean present_usage = true;
+    list.add(present_usage);
+    if (present_usage)
+      list.add(usage);
+
+    return list.hashCode();
   }
 
   @Override
@@ -433,11 +448,11 @@
               {
                 org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                 struct.tables = new ArrayList<String>(_list0.size);
-                for (int _i1 = 0; _i1 < _list0.size; ++_i1)
+                String _elem1;
+                for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                 {
-                  String _elem2;
-                  _elem2 = iprot.readString();
-                  struct.tables.add(_elem2);
+                  _elem1 = iprot.readString();
+                  struct.tables.add(_elem1);
                 }
                 iprot.readListEnd();
               }
@@ -531,11 +546,11 @@
         {
           org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
           struct.tables = new ArrayList<String>(_list5.size);
-          for (int _i6 = 0; _i6 < _list5.size; ++_i6)
+          String _elem6;
+          for (int _i7 = 0; _i7 < _list5.size; ++_i7)
           {
-            String _elem7;
-            _elem7 = iprot.readString();
-            struct.tables.add(_elem7);
+            _elem6 = iprot.readString();
+            struct.tables.add(_elem6);
           }
         }
         struct.setTablesIsSet(true);
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/Durability.java b/src/main/java/org/apache/accumulo/proxy/thrift/Durability.java
index fb4612a..daa16c8 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/Durability.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/Durability.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/IteratorScope.java b/src/main/java/org/apache/accumulo/proxy/thrift/IteratorScope.java
index 0fc8de8..65408bd 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/IteratorScope.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/IteratorScope.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/IteratorSetting.java b/src/main/java/org/apache/accumulo/proxy/thrift/IteratorSetting.java
index eabc686..826c46f 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/IteratorSetting.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/IteratorSetting.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class IteratorSetting implements org.apache.thrift.TBase<IteratorSetting, IteratorSetting._Fields>, java.io.Serializable, Cloneable, Comparable<IteratorSetting> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class IteratorSetting implements org.apache.thrift.TBase<IteratorSetting, IteratorSetting._Fields>, java.io.Serializable, Cloneable, Comparable<IteratorSetting> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("IteratorSetting");
 
   private static final org.apache.thrift.protocol.TField PRIORITY_FIELD_DESC = new org.apache.thrift.protocol.TField("priority", org.apache.thrift.protocol.TType.I32, (short)1);
@@ -348,7 +351,7 @@
   public Object getFieldValue(_Fields field) {
     switch (field) {
     case PRIORITY:
-      return Integer.valueOf(getPriority());
+      return getPriority();
 
     case NAME:
       return getName();
@@ -436,7 +439,29 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_priority = true;
+    list.add(present_priority);
+    if (present_priority)
+      list.add(priority);
+
+    boolean present_name = true && (isSetName());
+    list.add(present_name);
+    if (present_name)
+      list.add(name);
+
+    boolean present_iteratorClass = true && (isSetIteratorClass());
+    list.add(present_iteratorClass);
+    if (present_iteratorClass)
+      list.add(iteratorClass);
+
+    boolean present_properties = true && (isSetProperties());
+    list.add(present_properties);
+    if (present_properties)
+      list.add(properties);
+
+    return list.hashCode();
   }
 
   @Override
@@ -608,13 +633,13 @@
               {
                 org.apache.thrift.protocol.TMap _map16 = iprot.readMapBegin();
                 struct.properties = new HashMap<String,String>(2*_map16.size);
-                for (int _i17 = 0; _i17 < _map16.size; ++_i17)
+                String _key17;
+                String _val18;
+                for (int _i19 = 0; _i19 < _map16.size; ++_i19)
                 {
-                  String _key18;
-                  String _val19;
-                  _key18 = iprot.readString();
-                  _val19 = iprot.readString();
-                  struct.properties.put(_key18, _val19);
+                  _key17 = iprot.readString();
+                  _val18 = iprot.readString();
+                  struct.properties.put(_key17, _val18);
                 }
                 iprot.readMapEnd();
               }
@@ -736,13 +761,13 @@
         {
           org.apache.thrift.protocol.TMap _map22 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
           struct.properties = new HashMap<String,String>(2*_map22.size);
-          for (int _i23 = 0; _i23 < _map22.size; ++_i23)
+          String _key23;
+          String _val24;
+          for (int _i25 = 0; _i25 < _map22.size; ++_i25)
           {
-            String _key24;
-            String _val25;
-            _key24 = iprot.readString();
-            _val25 = iprot.readString();
-            struct.properties.put(_key24, _val25);
+            _key23 = iprot.readString();
+            _val24 = iprot.readString();
+            struct.properties.put(_key23, _val24);
           }
         }
         struct.setPropertiesIsSet(true);
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/Key.java b/src/main/java/org/apache/accumulo/proxy/thrift/Key.java
index 6984cf2..93237c5 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/Key.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/Key.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class Key implements org.apache.thrift.TBase<Key, Key._Fields>, java.io.Serializable, Cloneable, Comparable<Key> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class Key implements org.apache.thrift.TBase<Key, Key._Fields>, java.io.Serializable, Cloneable, Comparable<Key> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Key");
 
   private static final org.apache.thrift.protocol.TField ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("row", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -142,7 +145,7 @@
   // isset id assignments
   private static final int __TIMESTAMP_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
-  private _Fields optionals[] = {_Fields.TIMESTAMP};
+  private static final _Fields optionals[] = {_Fields.TIMESTAMP};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
@@ -172,10 +175,10 @@
     ByteBuffer colVisibility)
   {
     this();
-    this.row = row;
-    this.colFamily = colFamily;
-    this.colQualifier = colQualifier;
-    this.colVisibility = colVisibility;
+    this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
+    this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
+    this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
+    this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
   }
 
   /**
@@ -185,19 +188,15 @@
     __isset_bitfield = other.__isset_bitfield;
     if (other.isSetRow()) {
       this.row = org.apache.thrift.TBaseHelper.copyBinary(other.row);
-;
     }
     if (other.isSetColFamily()) {
       this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(other.colFamily);
-;
     }
     if (other.isSetColQualifier()) {
       this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(other.colQualifier);
-;
     }
     if (other.isSetColVisibility()) {
       this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(other.colVisibility);
-;
     }
     this.timestamp = other.timestamp;
   }
@@ -222,16 +221,16 @@
   }
 
   public ByteBuffer bufferForRow() {
-    return row;
+    return org.apache.thrift.TBaseHelper.copyBinary(row);
   }
 
   public Key setRow(byte[] row) {
-    setRow(row == null ? (ByteBuffer)null : ByteBuffer.wrap(row));
+    this.row = row == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(row, row.length));
     return this;
   }
 
   public Key setRow(ByteBuffer row) {
-    this.row = row;
+    this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
     return this;
   }
 
@@ -256,16 +255,16 @@
   }
 
   public ByteBuffer bufferForColFamily() {
-    return colFamily;
+    return org.apache.thrift.TBaseHelper.copyBinary(colFamily);
   }
 
   public Key setColFamily(byte[] colFamily) {
-    setColFamily(colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(colFamily));
+    this.colFamily = colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colFamily, colFamily.length));
     return this;
   }
 
   public Key setColFamily(ByteBuffer colFamily) {
-    this.colFamily = colFamily;
+    this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
     return this;
   }
 
@@ -290,16 +289,16 @@
   }
 
   public ByteBuffer bufferForColQualifier() {
-    return colQualifier;
+    return org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
   }
 
   public Key setColQualifier(byte[] colQualifier) {
-    setColQualifier(colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(colQualifier));
+    this.colQualifier = colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colQualifier, colQualifier.length));
     return this;
   }
 
   public Key setColQualifier(ByteBuffer colQualifier) {
-    this.colQualifier = colQualifier;
+    this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
     return this;
   }
 
@@ -324,16 +323,16 @@
   }
 
   public ByteBuffer bufferForColVisibility() {
-    return colVisibility;
+    return org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
   }
 
   public Key setColVisibility(byte[] colVisibility) {
-    setColVisibility(colVisibility == null ? (ByteBuffer)null : ByteBuffer.wrap(colVisibility));
+    this.colVisibility = colVisibility == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colVisibility, colVisibility.length));
     return this;
   }
 
   public Key setColVisibility(ByteBuffer colVisibility) {
-    this.colVisibility = colVisibility;
+    this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
     return this;
   }
 
@@ -435,7 +434,7 @@
       return getColVisibility();
 
     case TIMESTAMP:
-      return Long.valueOf(getTimestamp());
+      return getTimestamp();
 
     }
     throw new IllegalStateException();
@@ -525,7 +524,34 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_row = true && (isSetRow());
+    list.add(present_row);
+    if (present_row)
+      list.add(row);
+
+    boolean present_colFamily = true && (isSetColFamily());
+    list.add(present_colFamily);
+    if (present_colFamily)
+      list.add(colFamily);
+
+    boolean present_colQualifier = true && (isSetColQualifier());
+    list.add(present_colQualifier);
+    if (present_colQualifier)
+      list.add(colQualifier);
+
+    boolean present_colVisibility = true && (isSetColVisibility());
+    list.add(present_colVisibility);
+    if (present_colVisibility)
+      list.add(colVisibility);
+
+    boolean present_timestamp = true && (isSetTimestamp());
+    list.add(present_timestamp);
+    if (present_timestamp)
+      list.add(timestamp);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/KeyExtent.java b/src/main/java/org/apache/accumulo/proxy/thrift/KeyExtent.java
index 1136284..09001c6 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/KeyExtent.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/KeyExtent.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class KeyExtent implements org.apache.thrift.TBase<KeyExtent, KeyExtent._Fields>, java.io.Serializable, Cloneable, Comparable<KeyExtent> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class KeyExtent implements org.apache.thrift.TBase<KeyExtent, KeyExtent._Fields>, java.io.Serializable, Cloneable, Comparable<KeyExtent> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("KeyExtent");
 
   private static final org.apache.thrift.protocol.TField TABLE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("tableId", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -153,8 +156,8 @@
   {
     this();
     this.tableId = tableId;
-    this.endRow = endRow;
-    this.prevEndRow = prevEndRow;
+    this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
+    this.prevEndRow = org.apache.thrift.TBaseHelper.copyBinary(prevEndRow);
   }
 
   /**
@@ -166,11 +169,9 @@
     }
     if (other.isSetEndRow()) {
       this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
-;
     }
     if (other.isSetPrevEndRow()) {
       this.prevEndRow = org.apache.thrift.TBaseHelper.copyBinary(other.prevEndRow);
-;
     }
   }
 
@@ -215,16 +216,16 @@
   }
 
   public ByteBuffer bufferForEndRow() {
-    return endRow;
+    return org.apache.thrift.TBaseHelper.copyBinary(endRow);
   }
 
   public KeyExtent setEndRow(byte[] endRow) {
-    setEndRow(endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(endRow));
+    this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
     return this;
   }
 
   public KeyExtent setEndRow(ByteBuffer endRow) {
-    this.endRow = endRow;
+    this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
     return this;
   }
 
@@ -249,16 +250,16 @@
   }
 
   public ByteBuffer bufferForPrevEndRow() {
-    return prevEndRow;
+    return org.apache.thrift.TBaseHelper.copyBinary(prevEndRow);
   }
 
   public KeyExtent setPrevEndRow(byte[] prevEndRow) {
-    setPrevEndRow(prevEndRow == null ? (ByteBuffer)null : ByteBuffer.wrap(prevEndRow));
+    this.prevEndRow = prevEndRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(prevEndRow, prevEndRow.length));
     return this;
   }
 
   public KeyExtent setPrevEndRow(ByteBuffer prevEndRow) {
-    this.prevEndRow = prevEndRow;
+    this.prevEndRow = org.apache.thrift.TBaseHelper.copyBinary(prevEndRow);
     return this;
   }
 
@@ -383,7 +384,24 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_tableId = true && (isSetTableId());
+    list.add(present_tableId);
+    if (present_tableId)
+      list.add(tableId);
+
+    boolean present_endRow = true && (isSetEndRow());
+    list.add(present_endRow);
+    if (present_endRow)
+      list.add(endRow);
+
+    boolean present_prevEndRow = true && (isSetPrevEndRow());
+    list.add(present_prevEndRow);
+    if (present_prevEndRow)
+      list.add(prevEndRow);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/KeyValue.java b/src/main/java/org/apache/accumulo/proxy/thrift/KeyValue.java
index 76d71b5..480236c 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/KeyValue.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/KeyValue.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class KeyValue implements org.apache.thrift.TBase<KeyValue, KeyValue._Fields>, java.io.Serializable, Cloneable, Comparable<KeyValue> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class KeyValue implements org.apache.thrift.TBase<KeyValue, KeyValue._Fields>, java.io.Serializable, Cloneable, Comparable<KeyValue> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("KeyValue");
 
   private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRUCT, (short)1);
@@ -145,7 +148,7 @@
   {
     this();
     this.key = key;
-    this.value = value;
+    this.value = org.apache.thrift.TBaseHelper.copyBinary(value);
   }
 
   /**
@@ -157,7 +160,6 @@
     }
     if (other.isSetValue()) {
       this.value = org.apache.thrift.TBaseHelper.copyBinary(other.value);
-;
     }
   }
 
@@ -201,16 +203,16 @@
   }
 
   public ByteBuffer bufferForValue() {
-    return value;
+    return org.apache.thrift.TBaseHelper.copyBinary(value);
   }
 
   public KeyValue setValue(byte[] value) {
-    setValue(value == null ? (ByteBuffer)null : ByteBuffer.wrap(value));
+    this.value = value == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(value, value.length));
     return this;
   }
 
   public KeyValue setValue(ByteBuffer value) {
-    this.value = value;
+    this.value = org.apache.thrift.TBaseHelper.copyBinary(value);
     return this;
   }
 
@@ -313,7 +315,19 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_key = true && (isSetKey());
+    list.add(present_key);
+    if (present_key)
+      list.add(key);
+
+    boolean present_value = true && (isSetValue());
+    list.add(present_value);
+    if (present_value)
+      list.add(value);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/KeyValueAndPeek.java b/src/main/java/org/apache/accumulo/proxy/thrift/KeyValueAndPeek.java
index 88b0c3f..3bb4f13 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/KeyValueAndPeek.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/KeyValueAndPeek.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class KeyValueAndPeek implements org.apache.thrift.TBase<KeyValueAndPeek, KeyValueAndPeek._Fields>, java.io.Serializable, Cloneable, Comparable<KeyValueAndPeek> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class KeyValueAndPeek implements org.apache.thrift.TBase<KeyValueAndPeek, KeyValueAndPeek._Fields>, java.io.Serializable, Cloneable, Comparable<KeyValueAndPeek> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("KeyValueAndPeek");
 
   private static final org.apache.thrift.protocol.TField KEY_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("keyValue", org.apache.thrift.protocol.TType.STRUCT, (short)1);
@@ -247,7 +250,7 @@
       return getKeyValue();
 
     case HAS_NEXT:
-      return Boolean.valueOf(isHasNext());
+      return isHasNext();
 
     }
     throw new IllegalStateException();
@@ -304,7 +307,19 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_keyValue = true && (isSetKeyValue());
+    list.add(present_keyValue);
+    if (present_keyValue)
+      list.add(keyValue);
+
+    boolean present_hasNext = true;
+    list.add(present_hasNext);
+    if (present_hasNext)
+      list.add(hasNext);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/MutationsRejectedException.java b/src/main/java/org/apache/accumulo/proxy/thrift/MutationsRejectedException.java
index e5dfda1..db5b6c4 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/MutationsRejectedException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/MutationsRejectedException.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class MutationsRejectedException extends TException implements org.apache.thrift.TBase<MutationsRejectedException, MutationsRejectedException._Fields>, java.io.Serializable, Cloneable, Comparable<MutationsRejectedException> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class MutationsRejectedException extends TException implements org.apache.thrift.TBase<MutationsRejectedException, MutationsRejectedException._Fields>, java.io.Serializable, Cloneable, Comparable<MutationsRejectedException> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("MutationsRejectedException");
 
   private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -243,7 +246,14 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceExistsException.java b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceExistsException.java
new file mode 100644
index 0000000..db1a380
--- /dev/null
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceExistsException.java
@@ -0,0 +1,414 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.3)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.accumulo.proxy.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import org.apache.thrift.async.AsyncMethodCallback;
+import org.apache.thrift.server.AbstractNonblockingServer.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import javax.annotation.Generated;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class NamespaceExistsException extends TException implements org.apache.thrift.TBase<NamespaceExistsException, NamespaceExistsException._Fields>, java.io.Serializable, Cloneable, Comparable<NamespaceExistsException> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("NamespaceExistsException");
+
+  private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+  static {
+    schemes.put(StandardScheme.class, new NamespaceExistsExceptionStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new NamespaceExistsExceptionTupleSchemeFactory());
+  }
+
+  public String msg; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    MSG((short)1, "msg");
+
+    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // MSG
+          return MSG;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.MSG, new org.apache.thrift.meta_data.FieldMetaData("msg", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(NamespaceExistsException.class, metaDataMap);
+  }
+
+  public NamespaceExistsException() {
+  }
+
+  public NamespaceExistsException(
+    String msg)
+  {
+    this();
+    this.msg = msg;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public NamespaceExistsException(NamespaceExistsException other) {
+    if (other.isSetMsg()) {
+      this.msg = other.msg;
+    }
+  }
+
+  public NamespaceExistsException deepCopy() {
+    return new NamespaceExistsException(this);
+  }
+
+  @Override
+  public void clear() {
+    this.msg = null;
+  }
+
+  public String getMsg() {
+    return this.msg;
+  }
+
+  public NamespaceExistsException setMsg(String msg) {
+    this.msg = msg;
+    return this;
+  }
+
+  public void unsetMsg() {
+    this.msg = null;
+  }
+
+  /** Returns true if field msg is set (has been assigned a value) and false otherwise */
+  public boolean isSetMsg() {
+    return this.msg != null;
+  }
+
+  public void setMsgIsSet(boolean value) {
+    if (!value) {
+      this.msg = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, Object value) {
+    switch (field) {
+    case MSG:
+      if (value == null) {
+        unsetMsg();
+      } else {
+        setMsg((String)value);
+      }
+      break;
+
+    }
+  }
+
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case MSG:
+      return getMsg();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case MSG:
+      return isSetMsg();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof NamespaceExistsException)
+      return this.equals((NamespaceExistsException)that);
+    return false;
+  }
+
+  public boolean equals(NamespaceExistsException that) {
+    if (that == null)
+      return false;
+
+    boolean this_present_msg = true && this.isSetMsg();
+    boolean that_present_msg = true && that.isSetMsg();
+    if (this_present_msg || that_present_msg) {
+      if (!(this_present_msg && that_present_msg))
+        return false;
+      if (!this.msg.equals(that.msg))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
+  }
+
+  @Override
+  public int compareTo(NamespaceExistsException other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetMsg()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.msg, other.msg);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("NamespaceExistsException(");
+    boolean first = true;
+
+    sb.append("msg:");
+    if (this.msg == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.msg);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class NamespaceExistsExceptionStandardSchemeFactory implements SchemeFactory {
+    public NamespaceExistsExceptionStandardScheme getScheme() {
+      return new NamespaceExistsExceptionStandardScheme();
+    }
+  }
+
+  private static class NamespaceExistsExceptionStandardScheme extends StandardScheme<NamespaceExistsException> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, NamespaceExistsException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // MSG
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.msg = iprot.readString();
+              struct.setMsgIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, NamespaceExistsException struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.msg != null) {
+        oprot.writeFieldBegin(MSG_FIELD_DESC);
+        oprot.writeString(struct.msg);
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class NamespaceExistsExceptionTupleSchemeFactory implements SchemeFactory {
+    public NamespaceExistsExceptionTupleScheme getScheme() {
+      return new NamespaceExistsExceptionTupleScheme();
+    }
+  }
+
+  private static class NamespaceExistsExceptionTupleScheme extends TupleScheme<NamespaceExistsException> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, NamespaceExistsException struct) throws org.apache.thrift.TException {
+      TTupleProtocol oprot = (TTupleProtocol) prot;
+      BitSet optionals = new BitSet();
+      if (struct.isSetMsg()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetMsg()) {
+        oprot.writeString(struct.msg);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, NamespaceExistsException struct) throws org.apache.thrift.TException {
+      TTupleProtocol iprot = (TTupleProtocol) prot;
+      BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        struct.msg = iprot.readString();
+        struct.setMsgIsSet(true);
+      }
+    }
+  }
+
+}
+
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotEmptyException.java b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotEmptyException.java
new file mode 100644
index 0000000..f22320e
--- /dev/null
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotEmptyException.java
@@ -0,0 +1,414 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.3)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.accumulo.proxy.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import org.apache.thrift.async.AsyncMethodCallback;
+import org.apache.thrift.server.AbstractNonblockingServer.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import javax.annotation.Generated;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class NamespaceNotEmptyException extends TException implements org.apache.thrift.TBase<NamespaceNotEmptyException, NamespaceNotEmptyException._Fields>, java.io.Serializable, Cloneable, Comparable<NamespaceNotEmptyException> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("NamespaceNotEmptyException");
+
+  private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+  static {
+    schemes.put(StandardScheme.class, new NamespaceNotEmptyExceptionStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new NamespaceNotEmptyExceptionTupleSchemeFactory());
+  }
+
+  public String msg; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    MSG((short)1, "msg");
+
+    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // MSG
+          return MSG;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.MSG, new org.apache.thrift.meta_data.FieldMetaData("msg", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(NamespaceNotEmptyException.class, metaDataMap);
+  }
+
+  public NamespaceNotEmptyException() {
+  }
+
+  public NamespaceNotEmptyException(
+    String msg)
+  {
+    this();
+    this.msg = msg;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public NamespaceNotEmptyException(NamespaceNotEmptyException other) {
+    if (other.isSetMsg()) {
+      this.msg = other.msg;
+    }
+  }
+
+  public NamespaceNotEmptyException deepCopy() {
+    return new NamespaceNotEmptyException(this);
+  }
+
+  @Override
+  public void clear() {
+    this.msg = null;
+  }
+
+  public String getMsg() {
+    return this.msg;
+  }
+
+  public NamespaceNotEmptyException setMsg(String msg) {
+    this.msg = msg;
+    return this;
+  }
+
+  public void unsetMsg() {
+    this.msg = null;
+  }
+
+  /** Returns true if field msg is set (has been assigned a value) and false otherwise */
+  public boolean isSetMsg() {
+    return this.msg != null;
+  }
+
+  public void setMsgIsSet(boolean value) {
+    if (!value) {
+      this.msg = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, Object value) {
+    switch (field) {
+    case MSG:
+      if (value == null) {
+        unsetMsg();
+      } else {
+        setMsg((String)value);
+      }
+      break;
+
+    }
+  }
+
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case MSG:
+      return getMsg();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case MSG:
+      return isSetMsg();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof NamespaceNotEmptyException)
+      return this.equals((NamespaceNotEmptyException)that);
+    return false;
+  }
+
+  public boolean equals(NamespaceNotEmptyException that) {
+    if (that == null)
+      return false;
+
+    boolean this_present_msg = true && this.isSetMsg();
+    boolean that_present_msg = true && that.isSetMsg();
+    if (this_present_msg || that_present_msg) {
+      if (!(this_present_msg && that_present_msg))
+        return false;
+      if (!this.msg.equals(that.msg))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
+  }
+
+  @Override
+  public int compareTo(NamespaceNotEmptyException other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetMsg()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.msg, other.msg);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("NamespaceNotEmptyException(");
+    boolean first = true;
+
+    sb.append("msg:");
+    if (this.msg == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.msg);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class NamespaceNotEmptyExceptionStandardSchemeFactory implements SchemeFactory {
+    public NamespaceNotEmptyExceptionStandardScheme getScheme() {
+      return new NamespaceNotEmptyExceptionStandardScheme();
+    }
+  }
+
+  private static class NamespaceNotEmptyExceptionStandardScheme extends StandardScheme<NamespaceNotEmptyException> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, NamespaceNotEmptyException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // MSG
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.msg = iprot.readString();
+              struct.setMsgIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, NamespaceNotEmptyException struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.msg != null) {
+        oprot.writeFieldBegin(MSG_FIELD_DESC);
+        oprot.writeString(struct.msg);
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class NamespaceNotEmptyExceptionTupleSchemeFactory implements SchemeFactory {
+    public NamespaceNotEmptyExceptionTupleScheme getScheme() {
+      return new NamespaceNotEmptyExceptionTupleScheme();
+    }
+  }
+
+  private static class NamespaceNotEmptyExceptionTupleScheme extends TupleScheme<NamespaceNotEmptyException> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, NamespaceNotEmptyException struct) throws org.apache.thrift.TException {
+      TTupleProtocol oprot = (TTupleProtocol) prot;
+      BitSet optionals = new BitSet();
+      if (struct.isSetMsg()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetMsg()) {
+        oprot.writeString(struct.msg);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, NamespaceNotEmptyException struct) throws org.apache.thrift.TException {
+      TTupleProtocol iprot = (TTupleProtocol) prot;
+      BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        struct.msg = iprot.readString();
+        struct.setMsgIsSet(true);
+      }
+    }
+  }
+
+}
+
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotFoundException.java b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotFoundException.java
new file mode 100644
index 0000000..9e31e48
--- /dev/null
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotFoundException.java
@@ -0,0 +1,414 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.3)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.accumulo.proxy.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import org.apache.thrift.async.AsyncMethodCallback;
+import org.apache.thrift.server.AbstractNonblockingServer.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import javax.annotation.Generated;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class NamespaceNotFoundException extends TException implements org.apache.thrift.TBase<NamespaceNotFoundException, NamespaceNotFoundException._Fields>, java.io.Serializable, Cloneable, Comparable<NamespaceNotFoundException> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("NamespaceNotFoundException");
+
+  private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+  static {
+    schemes.put(StandardScheme.class, new NamespaceNotFoundExceptionStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new NamespaceNotFoundExceptionTupleSchemeFactory());
+  }
+
+  public String msg; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    MSG((short)1, "msg");
+
+    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // MSG
+          return MSG;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.MSG, new org.apache.thrift.meta_data.FieldMetaData("msg", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(NamespaceNotFoundException.class, metaDataMap);
+  }
+
+  public NamespaceNotFoundException() {
+  }
+
+  public NamespaceNotFoundException(
+    String msg)
+  {
+    this();
+    this.msg = msg;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public NamespaceNotFoundException(NamespaceNotFoundException other) {
+    if (other.isSetMsg()) {
+      this.msg = other.msg;
+    }
+  }
+
+  public NamespaceNotFoundException deepCopy() {
+    return new NamespaceNotFoundException(this);
+  }
+
+  @Override
+  public void clear() {
+    this.msg = null;
+  }
+
+  public String getMsg() {
+    return this.msg;
+  }
+
+  public NamespaceNotFoundException setMsg(String msg) {
+    this.msg = msg;
+    return this;
+  }
+
+  public void unsetMsg() {
+    this.msg = null;
+  }
+
+  /** Returns true if field msg is set (has been assigned a value) and false otherwise */
+  public boolean isSetMsg() {
+    return this.msg != null;
+  }
+
+  public void setMsgIsSet(boolean value) {
+    if (!value) {
+      this.msg = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, Object value) {
+    switch (field) {
+    case MSG:
+      if (value == null) {
+        unsetMsg();
+      } else {
+        setMsg((String)value);
+      }
+      break;
+
+    }
+  }
+
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case MSG:
+      return getMsg();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case MSG:
+      return isSetMsg();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof NamespaceNotFoundException)
+      return this.equals((NamespaceNotFoundException)that);
+    return false;
+  }
+
+  public boolean equals(NamespaceNotFoundException that) {
+    if (that == null)
+      return false;
+
+    boolean this_present_msg = true && this.isSetMsg();
+    boolean that_present_msg = true && that.isSetMsg();
+    if (this_present_msg || that_present_msg) {
+      if (!(this_present_msg && that_present_msg))
+        return false;
+      if (!this.msg.equals(that.msg))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
+  }
+
+  @Override
+  public int compareTo(NamespaceNotFoundException other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetMsg()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.msg, other.msg);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("NamespaceNotFoundException(");
+    boolean first = true;
+
+    sb.append("msg:");
+    if (this.msg == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.msg);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class NamespaceNotFoundExceptionStandardSchemeFactory implements SchemeFactory {
+    public NamespaceNotFoundExceptionStandardScheme getScheme() {
+      return new NamespaceNotFoundExceptionStandardScheme();
+    }
+  }
+
+  private static class NamespaceNotFoundExceptionStandardScheme extends StandardScheme<NamespaceNotFoundException> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, NamespaceNotFoundException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // MSG
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.msg = iprot.readString();
+              struct.setMsgIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, NamespaceNotFoundException struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.msg != null) {
+        oprot.writeFieldBegin(MSG_FIELD_DESC);
+        oprot.writeString(struct.msg);
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class NamespaceNotFoundExceptionTupleSchemeFactory implements SchemeFactory {
+    public NamespaceNotFoundExceptionTupleScheme getScheme() {
+      return new NamespaceNotFoundExceptionTupleScheme();
+    }
+  }
+
+  private static class NamespaceNotFoundExceptionTupleScheme extends TupleScheme<NamespaceNotFoundException> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, NamespaceNotFoundException struct) throws org.apache.thrift.TException {
+      TTupleProtocol oprot = (TTupleProtocol) prot;
+      BitSet optionals = new BitSet();
+      if (struct.isSetMsg()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetMsg()) {
+        oprot.writeString(struct.msg);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, NamespaceNotFoundException struct) throws org.apache.thrift.TException {
+      TTupleProtocol iprot = (TTupleProtocol) prot;
+      BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        struct.msg = iprot.readString();
+        struct.setMsgIsSet(true);
+      }
+    }
+  }
+
+}
+
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/NamespacePermission.java b/src/main/java/org/apache/accumulo/proxy/thrift/NamespacePermission.java
new file mode 100644
index 0000000..6d790f6
--- /dev/null
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/NamespacePermission.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.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.3)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.accumulo.proxy.thrift;
+
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.thrift.TEnum;
+
+@SuppressWarnings({"unused"}) public enum NamespacePermission implements org.apache.thrift.TEnum {
+  READ(0),
+  WRITE(1),
+  ALTER_NAMESPACE(2),
+  GRANT(3),
+  ALTER_TABLE(4),
+  CREATE_TABLE(5),
+  DROP_TABLE(6),
+  BULK_IMPORT(7),
+  DROP_NAMESPACE(8);
+
+  private final int value;
+
+  private NamespacePermission(int value) {
+    this.value = value;
+  }
+
+  /**
+   * Get the integer value of this enum value, as defined in the Thrift IDL.
+   */
+  public int getValue() {
+    return value;
+  }
+
+  /**
+   * Find a the enum type by its integer value, as defined in the Thrift IDL.
+   * @return null if the value is not found.
+   */
+  public static NamespacePermission findByValue(int value) { 
+    switch (value) {
+      case 0:
+        return READ;
+      case 1:
+        return WRITE;
+      case 2:
+        return ALTER_NAMESPACE;
+      case 3:
+        return GRANT;
+      case 4:
+        return ALTER_TABLE;
+      case 5:
+        return CREATE_TABLE;
+      case 6:
+        return DROP_TABLE;
+      case 7:
+        return BULK_IMPORT;
+      case 8:
+        return DROP_NAMESPACE;
+      default:
+        return null;
+    }
+  }
+}
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/NoMoreEntriesException.java b/src/main/java/org/apache/accumulo/proxy/thrift/NoMoreEntriesException.java
index d67bcd2..182277a 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/NoMoreEntriesException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/NoMoreEntriesException.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class NoMoreEntriesException extends TException implements org.apache.thrift.TBase<NoMoreEntriesException, NoMoreEntriesException._Fields>, java.io.Serializable, Cloneable, Comparable<NoMoreEntriesException> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class NoMoreEntriesException extends TException implements org.apache.thrift.TBase<NoMoreEntriesException, NoMoreEntriesException._Fields>, java.io.Serializable, Cloneable, Comparable<NoMoreEntriesException> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("NoMoreEntriesException");
 
   private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -243,7 +246,14 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/PartialKey.java b/src/main/java/org/apache/accumulo/proxy/thrift/PartialKey.java
index 2a0f269..b03eae9 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/PartialKey.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/PartialKey.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/Range.java b/src/main/java/org/apache/accumulo/proxy/thrift/Range.java
index bc66c6b..db8fe8e 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/Range.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/Range.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class Range implements org.apache.thrift.TBase<Range, Range._Fields>, java.io.Serializable, Cloneable, Comparable<Range> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class Range implements org.apache.thrift.TBase<Range, Range._Fields>, java.io.Serializable, Cloneable, Comparable<Range> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Range");
 
   private static final org.apache.thrift.protocol.TField START_FIELD_DESC = new org.apache.thrift.protocol.TField("start", org.apache.thrift.protocol.TType.STRUCT, (short)1);
@@ -337,13 +340,13 @@
       return getStart();
 
     case START_INCLUSIVE:
-      return Boolean.valueOf(isStartInclusive());
+      return isStartInclusive();
 
     case STOP:
       return getStop();
 
     case STOP_INCLUSIVE:
-      return Boolean.valueOf(isStopInclusive());
+      return isStopInclusive();
 
     }
     throw new IllegalStateException();
@@ -422,7 +425,29 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_start = true && (isSetStart());
+    list.add(present_start);
+    if (present_start)
+      list.add(start);
+
+    boolean present_startInclusive = true;
+    list.add(present_startInclusive);
+    if (present_startInclusive)
+      list.add(startInclusive);
+
+    boolean present_stop = true && (isSetStop());
+    list.add(present_stop);
+    if (present_stop)
+      list.add(stop);
+
+    boolean present_stopInclusive = true;
+    list.add(present_stopInclusive);
+    if (present_stopInclusive)
+      list.add(stopInclusive);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ScanColumn.java b/src/main/java/org/apache/accumulo/proxy/thrift/ScanColumn.java
index 296c885..3cea424 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ScanColumn.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ScanColumn.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class ScanColumn implements org.apache.thrift.TBase<ScanColumn, ScanColumn._Fields>, java.io.Serializable, Cloneable, Comparable<ScanColumn> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class ScanColumn implements org.apache.thrift.TBase<ScanColumn, ScanColumn._Fields>, java.io.Serializable, Cloneable, Comparable<ScanColumn> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ScanColumn");
 
   private static final org.apache.thrift.protocol.TField COL_FAMILY_FIELD_DESC = new org.apache.thrift.protocol.TField("colFamily", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -125,7 +128,7 @@
   }
 
   // isset id assignments
-  private _Fields optionals[] = {_Fields.COL_QUALIFIER};
+  private static final _Fields optionals[] = {_Fields.COL_QUALIFIER};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
@@ -144,7 +147,7 @@
     ByteBuffer colFamily)
   {
     this();
-    this.colFamily = colFamily;
+    this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
   }
 
   /**
@@ -153,11 +156,9 @@
   public ScanColumn(ScanColumn other) {
     if (other.isSetColFamily()) {
       this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(other.colFamily);
-;
     }
     if (other.isSetColQualifier()) {
       this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(other.colQualifier);
-;
     }
   }
 
@@ -177,16 +178,16 @@
   }
 
   public ByteBuffer bufferForColFamily() {
-    return colFamily;
+    return org.apache.thrift.TBaseHelper.copyBinary(colFamily);
   }
 
   public ScanColumn setColFamily(byte[] colFamily) {
-    setColFamily(colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(colFamily));
+    this.colFamily = colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colFamily, colFamily.length));
     return this;
   }
 
   public ScanColumn setColFamily(ByteBuffer colFamily) {
-    this.colFamily = colFamily;
+    this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
     return this;
   }
 
@@ -211,16 +212,16 @@
   }
 
   public ByteBuffer bufferForColQualifier() {
-    return colQualifier;
+    return org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
   }
 
   public ScanColumn setColQualifier(byte[] colQualifier) {
-    setColQualifier(colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(colQualifier));
+    this.colQualifier = colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colQualifier, colQualifier.length));
     return this;
   }
 
   public ScanColumn setColQualifier(ByteBuffer colQualifier) {
-    this.colQualifier = colQualifier;
+    this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
     return this;
   }
 
@@ -323,7 +324,19 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_colFamily = true && (isSetColFamily());
+    list.add(present_colFamily);
+    if (present_colFamily)
+      list.add(colFamily);
+
+    boolean present_colQualifier = true && (isSetColQualifier());
+    list.add(present_colQualifier);
+    if (present_colQualifier)
+      list.add(colQualifier);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ScanOptions.java b/src/main/java/org/apache/accumulo/proxy/thrift/ScanOptions.java
index 047daa0..6675c8e 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ScanOptions.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ScanOptions.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class ScanOptions implements org.apache.thrift.TBase<ScanOptions, ScanOptions._Fields>, java.io.Serializable, Cloneable, Comparable<ScanOptions> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class ScanOptions implements org.apache.thrift.TBase<ScanOptions, ScanOptions._Fields>, java.io.Serializable, Cloneable, Comparable<ScanOptions> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ScanOptions");
 
   private static final org.apache.thrift.protocol.TField AUTHORIZATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("authorizations", org.apache.thrift.protocol.TType.SET, (short)1);
@@ -142,7 +145,7 @@
   // isset id assignments
   private static final int __BUFFERSIZE_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
-  private _Fields optionals[] = {_Fields.AUTHORIZATIONS,_Fields.RANGE,_Fields.COLUMNS,_Fields.ITERATORS,_Fields.BUFFER_SIZE};
+  private static final _Fields optionals[] = {_Fields.AUTHORIZATIONS,_Fields.RANGE,_Fields.COLUMNS,_Fields.ITERATORS,_Fields.BUFFER_SIZE};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
@@ -433,7 +436,7 @@
       return getIterators();
 
     case BUFFER_SIZE:
-      return Integer.valueOf(getBufferSize());
+      return getBufferSize();
 
     }
     throw new IllegalStateException();
@@ -523,7 +526,34 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_authorizations = true && (isSetAuthorizations());
+    list.add(present_authorizations);
+    if (present_authorizations)
+      list.add(authorizations);
+
+    boolean present_range = true && (isSetRange());
+    list.add(present_range);
+    if (present_range)
+      list.add(range);
+
+    boolean present_columns = true && (isSetColumns());
+    list.add(present_columns);
+    if (present_columns)
+      list.add(columns);
+
+    boolean present_iterators = true && (isSetIterators());
+    list.add(present_iterators);
+    if (present_iterators)
+      list.add(iterators);
+
+    boolean present_bufferSize = true && (isSetBufferSize());
+    list.add(present_bufferSize);
+    if (present_bufferSize)
+      list.add(bufferSize);
+
+    return list.hashCode();
   }
 
   @Override
@@ -609,7 +639,7 @@
       if (this.authorizations == null) {
         sb.append("null");
       } else {
-        sb.append(this.authorizations);
+        org.apache.thrift.TBaseHelper.toString(this.authorizations, sb);
       }
       first = false;
     }
@@ -702,11 +732,11 @@
               {
                 org.apache.thrift.protocol.TSet _set26 = iprot.readSetBegin();
                 struct.authorizations = new HashSet<ByteBuffer>(2*_set26.size);
-                for (int _i27 = 0; _i27 < _set26.size; ++_i27)
+                ByteBuffer _elem27;
+                for (int _i28 = 0; _i28 < _set26.size; ++_i28)
                 {
-                  ByteBuffer _elem28;
-                  _elem28 = iprot.readBinary();
-                  struct.authorizations.add(_elem28);
+                  _elem27 = iprot.readBinary();
+                  struct.authorizations.add(_elem27);
                 }
                 iprot.readSetEnd();
               }
@@ -729,12 +759,12 @@
               {
                 org.apache.thrift.protocol.TList _list29 = iprot.readListBegin();
                 struct.columns = new ArrayList<ScanColumn>(_list29.size);
-                for (int _i30 = 0; _i30 < _list29.size; ++_i30)
+                ScanColumn _elem30;
+                for (int _i31 = 0; _i31 < _list29.size; ++_i31)
                 {
-                  ScanColumn _elem31;
-                  _elem31 = new ScanColumn();
-                  _elem31.read(iprot);
-                  struct.columns.add(_elem31);
+                  _elem30 = new ScanColumn();
+                  _elem30.read(iprot);
+                  struct.columns.add(_elem30);
                 }
                 iprot.readListEnd();
               }
@@ -748,12 +778,12 @@
               {
                 org.apache.thrift.protocol.TList _list32 = iprot.readListBegin();
                 struct.iterators = new ArrayList<IteratorSetting>(_list32.size);
-                for (int _i33 = 0; _i33 < _list32.size; ++_i33)
+                IteratorSetting _elem33;
+                for (int _i34 = 0; _i34 < _list32.size; ++_i34)
                 {
-                  IteratorSetting _elem34;
-                  _elem34 = new IteratorSetting();
-                  _elem34.read(iprot);
-                  struct.iterators.add(_elem34);
+                  _elem33 = new IteratorSetting();
+                  _elem33.read(iprot);
+                  struct.iterators.add(_elem33);
                 }
                 iprot.readListEnd();
               }
@@ -916,11 +946,11 @@
         {
           org.apache.thrift.protocol.TSet _set41 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
           struct.authorizations = new HashSet<ByteBuffer>(2*_set41.size);
-          for (int _i42 = 0; _i42 < _set41.size; ++_i42)
+          ByteBuffer _elem42;
+          for (int _i43 = 0; _i43 < _set41.size; ++_i43)
           {
-            ByteBuffer _elem43;
-            _elem43 = iprot.readBinary();
-            struct.authorizations.add(_elem43);
+            _elem42 = iprot.readBinary();
+            struct.authorizations.add(_elem42);
           }
         }
         struct.setAuthorizationsIsSet(true);
@@ -934,12 +964,12 @@
         {
           org.apache.thrift.protocol.TList _list44 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.columns = new ArrayList<ScanColumn>(_list44.size);
-          for (int _i45 = 0; _i45 < _list44.size; ++_i45)
+          ScanColumn _elem45;
+          for (int _i46 = 0; _i46 < _list44.size; ++_i46)
           {
-            ScanColumn _elem46;
-            _elem46 = new ScanColumn();
-            _elem46.read(iprot);
-            struct.columns.add(_elem46);
+            _elem45 = new ScanColumn();
+            _elem45.read(iprot);
+            struct.columns.add(_elem45);
           }
         }
         struct.setColumnsIsSet(true);
@@ -948,12 +978,12 @@
         {
           org.apache.thrift.protocol.TList _list47 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.iterators = new ArrayList<IteratorSetting>(_list47.size);
-          for (int _i48 = 0; _i48 < _list47.size; ++_i48)
+          IteratorSetting _elem48;
+          for (int _i49 = 0; _i49 < _list47.size; ++_i49)
           {
-            IteratorSetting _elem49;
-            _elem49 = new IteratorSetting();
-            _elem49.read(iprot);
-            struct.iterators.add(_elem49);
+            _elem48 = new IteratorSetting();
+            _elem48.read(iprot);
+            struct.iterators.add(_elem48);
           }
         }
         struct.setIteratorsIsSet(true);
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ScanResult.java b/src/main/java/org/apache/accumulo/proxy/thrift/ScanResult.java
index 3775e7d..861b0de 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ScanResult.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ScanResult.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class ScanResult implements org.apache.thrift.TBase<ScanResult, ScanResult._Fields>, java.io.Serializable, Cloneable, Comparable<ScanResult> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class ScanResult implements org.apache.thrift.TBase<ScanResult, ScanResult._Fields>, java.io.Serializable, Cloneable, Comparable<ScanResult> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ScanResult");
 
   private static final org.apache.thrift.protocol.TField RESULTS_FIELD_DESC = new org.apache.thrift.protocol.TField("results", org.apache.thrift.protocol.TType.LIST, (short)1);
@@ -267,7 +270,7 @@
       return getResults();
 
     case MORE:
-      return Boolean.valueOf(isMore());
+      return isMore();
 
     }
     throw new IllegalStateException();
@@ -324,7 +327,19 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_results = true && (isSetResults());
+    list.add(present_results);
+    if (present_results)
+      list.add(results);
+
+    boolean present_more = true;
+    list.add(present_more);
+    if (present_more)
+      list.add(more);
+
+    return list.hashCode();
   }
 
   @Override
@@ -436,12 +451,12 @@
               {
                 org.apache.thrift.protocol.TList _list8 = iprot.readListBegin();
                 struct.results = new ArrayList<KeyValue>(_list8.size);
-                for (int _i9 = 0; _i9 < _list8.size; ++_i9)
+                KeyValue _elem9;
+                for (int _i10 = 0; _i10 < _list8.size; ++_i10)
                 {
-                  KeyValue _elem10;
-                  _elem10 = new KeyValue();
-                  _elem10.read(iprot);
-                  struct.results.add(_elem10);
+                  _elem9 = new KeyValue();
+                  _elem9.read(iprot);
+                  struct.results.add(_elem9);
                 }
                 iprot.readListEnd();
               }
@@ -535,12 +550,12 @@
         {
           org.apache.thrift.protocol.TList _list13 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
           struct.results = new ArrayList<KeyValue>(_list13.size);
-          for (int _i14 = 0; _i14 < _list13.size; ++_i14)
+          KeyValue _elem14;
+          for (int _i15 = 0; _i15 < _list13.size; ++_i15)
           {
-            KeyValue _elem15;
-            _elem15 = new KeyValue();
-            _elem15.read(iprot);
-            struct.results.add(_elem15);
+            _elem14 = new KeyValue();
+            _elem14.read(iprot);
+            struct.results.add(_elem14);
           }
         }
         struct.setResultsIsSet(true);
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ScanState.java b/src/main/java/org/apache/accumulo/proxy/thrift/ScanState.java
index 127d147..8e79212 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ScanState.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ScanState.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/ScanType.java b/src/main/java/org/apache/accumulo/proxy/thrift/ScanType.java
index f417110..14ac9ce 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ScanType.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ScanType.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/SystemPermission.java b/src/main/java/org/apache/accumulo/proxy/thrift/SystemPermission.java
index 6ebb69a..6671dec 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/SystemPermission.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/SystemPermission.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/TableExistsException.java b/src/main/java/org/apache/accumulo/proxy/thrift/TableExistsException.java
index 9e3cf9c..509f022 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/TableExistsException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/TableExistsException.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class TableExistsException extends TException implements org.apache.thrift.TBase<TableExistsException, TableExistsException._Fields>, java.io.Serializable, Cloneable, Comparable<TableExistsException> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class TableExistsException extends TException implements org.apache.thrift.TBase<TableExistsException, TableExistsException._Fields>, java.io.Serializable, Cloneable, Comparable<TableExistsException> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TableExistsException");
 
   private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -243,7 +246,14 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/TableNotFoundException.java b/src/main/java/org/apache/accumulo/proxy/thrift/TableNotFoundException.java
index f12059b..d889faf 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/TableNotFoundException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/TableNotFoundException.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class TableNotFoundException extends TException implements org.apache.thrift.TBase<TableNotFoundException, TableNotFoundException._Fields>, java.io.Serializable, Cloneable, Comparable<TableNotFoundException> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class TableNotFoundException extends TException implements org.apache.thrift.TBase<TableNotFoundException, TableNotFoundException._Fields>, java.io.Serializable, Cloneable, Comparable<TableNotFoundException> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TableNotFoundException");
 
   private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -243,7 +246,14 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/TablePermission.java b/src/main/java/org/apache/accumulo/proxy/thrift/TablePermission.java
index 04882fa..1beac63 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/TablePermission.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/TablePermission.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/TimeType.java b/src/main/java/org/apache/accumulo/proxy/thrift/TimeType.java
index 32564e0..26565a2 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/TimeType.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/TimeType.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/UnknownScanner.java b/src/main/java/org/apache/accumulo/proxy/thrift/UnknownScanner.java
index f6a4b1e..3630f94 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/UnknownScanner.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/UnknownScanner.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class UnknownScanner extends TException implements org.apache.thrift.TBase<UnknownScanner, UnknownScanner._Fields>, java.io.Serializable, Cloneable, Comparable<UnknownScanner> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class UnknownScanner extends TException implements org.apache.thrift.TBase<UnknownScanner, UnknownScanner._Fields>, java.io.Serializable, Cloneable, Comparable<UnknownScanner> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("UnknownScanner");
 
   private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -243,7 +246,14 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/UnknownWriter.java b/src/main/java/org/apache/accumulo/proxy/thrift/UnknownWriter.java
index 661aa1b..cd82742 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/UnknownWriter.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/UnknownWriter.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class UnknownWriter extends TException implements org.apache.thrift.TBase<UnknownWriter, UnknownWriter._Fields>, java.io.Serializable, Cloneable, Comparable<UnknownWriter> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class UnknownWriter extends TException implements org.apache.thrift.TBase<UnknownWriter, UnknownWriter._Fields>, java.io.Serializable, Cloneable, Comparable<UnknownWriter> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("UnknownWriter");
 
   private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)1);
@@ -243,7 +246,14 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_msg = true && (isSetMsg());
+    list.add(present_msg);
+    if (present_msg)
+      list.add(msg);
+
+    return list.hashCode();
   }
 
   @Override
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/WriterOptions.java b/src/main/java/org/apache/accumulo/proxy/thrift/WriterOptions.java
index 7ecde35..02d4548 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/WriterOptions.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/WriterOptions.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.1)
+ * Autogenerated by Thrift Compiler (0.9.3)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -45,10 +45,13 @@
 import java.util.BitSet;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import javax.annotation.Generated;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class WriterOptions implements org.apache.thrift.TBase<WriterOptions, WriterOptions._Fields>, java.io.Serializable, Cloneable, Comparable<WriterOptions> {
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
+public class WriterOptions implements org.apache.thrift.TBase<WriterOptions, WriterOptions._Fields>, java.io.Serializable, Cloneable, Comparable<WriterOptions> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("WriterOptions");
 
   private static final org.apache.thrift.protocol.TField MAX_MEMORY_FIELD_DESC = new org.apache.thrift.protocol.TField("maxMemory", org.apache.thrift.protocol.TType.I64, (short)1);
@@ -153,7 +156,7 @@
   private static final int __TIMEOUTMS_ISSET_ID = 2;
   private static final int __THREADS_ISSET_ID = 3;
   private byte __isset_bitfield = 0;
-  private _Fields optionals[] = {_Fields.DURABILITY};
+  private static final _Fields optionals[] = {_Fields.DURABILITY};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
@@ -394,16 +397,16 @@
   public Object getFieldValue(_Fields field) {
     switch (field) {
     case MAX_MEMORY:
-      return Long.valueOf(getMaxMemory());
+      return getMaxMemory();
 
     case LATENCY_MS:
-      return Long.valueOf(getLatencyMs());
+      return getLatencyMs();
 
     case TIMEOUT_MS:
-      return Long.valueOf(getTimeoutMs());
+      return getTimeoutMs();
 
     case THREADS:
-      return Integer.valueOf(getThreads());
+      return getThreads();
 
     case DURABILITY:
       return getDurability();
@@ -496,7 +499,34 @@
 
   @Override
   public int hashCode() {
-    return 0;
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_maxMemory = true;
+    list.add(present_maxMemory);
+    if (present_maxMemory)
+      list.add(maxMemory);
+
+    boolean present_latencyMs = true;
+    list.add(present_latencyMs);
+    if (present_latencyMs)
+      list.add(latencyMs);
+
+    boolean present_timeoutMs = true;
+    list.add(present_timeoutMs);
+    if (present_timeoutMs)
+      list.add(timeoutMs);
+
+    boolean present_threads = true;
+    list.add(present_threads);
+    if (present_threads)
+      list.add(threads);
+
+    boolean present_durability = true && (isSetDurability());
+    list.add(present_durability);
+    if (present_durability)
+      list.add(durability.getValue());
+
+    return list.hashCode();
   }
 
   @Override
@@ -681,7 +711,7 @@
             break;
           case 5: // DURABILITY
             if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
-              struct.durability = Durability.findByValue(iprot.readI32());
+              struct.durability = org.apache.accumulo.proxy.thrift.Durability.findByValue(iprot.readI32());
               struct.setDurabilityIsSet(true);
             } else { 
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -793,7 +823,7 @@
         struct.setThreadsIsSet(true);
       }
       if (incoming.get(4)) {
-        struct.durability = Durability.findByValue(iprot.readI32());
+        struct.durability = org.apache.accumulo.proxy.thrift.Durability.findByValue(iprot.readI32());
         struct.setDurabilityIsSet(true);
       }
     }
diff --git a/src/main/python/AccumuloProxy-remote b/src/main/python/AccumuloProxy-remote
index a8d7542..bc08e9b 100644
--- a/src/main/python/AccumuloProxy-remote
+++ b/src/main/python/AccumuloProxy-remote
@@ -14,7 +14,7 @@
 # limitations under the License.
 #!/usr/bin/env python
 #
-# Autogenerated by Thrift Compiler (0.9.1)
+# Autogenerated by Thrift Compiler (0.9.3)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
@@ -26,6 +26,7 @@
 from urlparse import urlparse
 from thrift.transport import TTransport
 from thrift.transport import TSocket
+from thrift.transport import TSSLSocket
 from thrift.transport import THttpClient
 from thrift.protocol import TBinaryProtocol
 
@@ -33,88 +34,111 @@
 from accumulo.ttypes import *
 
 if len(sys.argv) <= 1 or sys.argv[1] == '--help':
-  print ''
-  print 'Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] function [arg1 [arg2...]]'
-  print ''
-  print 'Functions:'
-  print '  string login(string principal,  loginProperties)'
-  print '  i32 addConstraint(string login, string tableName, string constraintClassName)'
-  print '  void addSplits(string login, string tableName,  splits)'
-  print '  void attachIterator(string login, string tableName, IteratorSetting setting,  scopes)'
-  print '  void checkIteratorConflicts(string login, string tableName, IteratorSetting setting,  scopes)'
-  print '  void clearLocatorCache(string login, string tableName)'
-  print '  void cloneTable(string login, string tableName, string newTableName, bool flush,  propertiesToSet,  propertiesToExclude)'
-  print '  void compactTable(string login, string tableName, string startRow, string endRow,  iterators, bool flush, bool wait, CompactionStrategyConfig compactionStrategy)'
-  print '  void cancelCompaction(string login, string tableName)'
-  print '  void createTable(string login, string tableName, bool versioningIter, TimeType type)'
-  print '  void deleteTable(string login, string tableName)'
-  print '  void deleteRows(string login, string tableName, string startRow, string endRow)'
-  print '  void exportTable(string login, string tableName, string exportDir)'
-  print '  void flushTable(string login, string tableName, string startRow, string endRow, bool wait)'
-  print '   getDiskUsage(string login,  tables)'
-  print '   getLocalityGroups(string login, string tableName)'
-  print '  IteratorSetting getIteratorSetting(string login, string tableName, string iteratorName, IteratorScope scope)'
-  print '  string getMaxRow(string login, string tableName,  auths, string startRow, bool startInclusive, string endRow, bool endInclusive)'
-  print '   getTableProperties(string login, string tableName)'
-  print '  void importDirectory(string login, string tableName, string importDir, string failureDir, bool setTime)'
-  print '  void importTable(string login, string tableName, string importDir)'
-  print '   listSplits(string login, string tableName, i32 maxSplits)'
-  print '   listTables(string login)'
-  print '   listIterators(string login, string tableName)'
-  print '   listConstraints(string login, string tableName)'
-  print '  void mergeTablets(string login, string tableName, string startRow, string endRow)'
-  print '  void offlineTable(string login, string tableName, bool wait)'
-  print '  void onlineTable(string login, string tableName, bool wait)'
-  print '  void removeConstraint(string login, string tableName, i32 constraint)'
-  print '  void removeIterator(string login, string tableName, string iterName,  scopes)'
-  print '  void removeTableProperty(string login, string tableName, string property)'
-  print '  void renameTable(string login, string oldTableName, string newTableName)'
-  print '  void setLocalityGroups(string login, string tableName,  groups)'
-  print '  void setTableProperty(string login, string tableName, string property, string value)'
-  print '   splitRangeByTablets(string login, string tableName, Range range, i32 maxSplits)'
-  print '  bool tableExists(string login, string tableName)'
-  print '   tableIdMap(string login)'
-  print '  bool testTableClassLoad(string login, string tableName, string className, string asTypeName)'
-  print '  void pingTabletServer(string login, string tserver)'
-  print '   getActiveScans(string login, string tserver)'
-  print '   getActiveCompactions(string login, string tserver)'
-  print '   getSiteConfiguration(string login)'
-  print '   getSystemConfiguration(string login)'
-  print '   getTabletServers(string login)'
-  print '  void removeProperty(string login, string property)'
-  print '  void setProperty(string login, string property, string value)'
-  print '  bool testClassLoad(string login, string className, string asTypeName)'
-  print '  bool authenticateUser(string login, string user,  properties)'
-  print '  void changeUserAuthorizations(string login, string user,  authorizations)'
-  print '  void changeLocalUserPassword(string login, string user, string password)'
-  print '  void createLocalUser(string login, string user, string password)'
-  print '  void dropLocalUser(string login, string user)'
-  print '   getUserAuthorizations(string login, string user)'
-  print '  void grantSystemPermission(string login, string user, SystemPermission perm)'
-  print '  void grantTablePermission(string login, string user, string table, TablePermission perm)'
-  print '  bool hasSystemPermission(string login, string user, SystemPermission perm)'
-  print '  bool hasTablePermission(string login, string user, string table, TablePermission perm)'
-  print '   listLocalUsers(string login)'
-  print '  void revokeSystemPermission(string login, string user, SystemPermission perm)'
-  print '  void revokeTablePermission(string login, string user, string table, TablePermission perm)'
-  print '  string createBatchScanner(string login, string tableName, BatchScanOptions options)'
-  print '  string createScanner(string login, string tableName, ScanOptions options)'
-  print '  bool hasNext(string scanner)'
-  print '  KeyValueAndPeek nextEntry(string scanner)'
-  print '  ScanResult nextK(string scanner, i32 k)'
-  print '  void closeScanner(string scanner)'
-  print '  void updateAndFlush(string login, string tableName,  cells)'
-  print '  string createWriter(string login, string tableName, WriterOptions opts)'
-  print '  void update(string writer,  cells)'
-  print '  void flush(string writer)'
-  print '  void closeWriter(string writer)'
-  print '  ConditionalStatus updateRowConditionally(string login, string tableName, string row, ConditionalUpdates updates)'
-  print '  string createConditionalWriter(string login, string tableName, ConditionalWriterOptions options)'
-  print '   updateRowsConditionally(string conditionalWriter,  updates)'
-  print '  void closeConditionalWriter(string conditionalWriter)'
-  print '  Range getRowRange(string row)'
-  print '  Key getFollowing(Key key, PartialKey part)'
-  print ''
+  print('')
+  print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] function [arg1 [arg2...]]')
+  print('')
+  print('Functions:')
+  print('  string login(string principal,  loginProperties)')
+  print('  i32 addConstraint(string login, string tableName, string constraintClassName)')
+  print('  void addSplits(string login, string tableName,  splits)')
+  print('  void attachIterator(string login, string tableName, IteratorSetting setting,  scopes)')
+  print('  void checkIteratorConflicts(string login, string tableName, IteratorSetting setting,  scopes)')
+  print('  void clearLocatorCache(string login, string tableName)')
+  print('  void cloneTable(string login, string tableName, string newTableName, bool flush,  propertiesToSet,  propertiesToExclude)')
+  print('  void compactTable(string login, string tableName, string startRow, string endRow,  iterators, bool flush, bool wait, CompactionStrategyConfig compactionStrategy)')
+  print('  void cancelCompaction(string login, string tableName)')
+  print('  void createTable(string login, string tableName, bool versioningIter, TimeType type)')
+  print('  void deleteTable(string login, string tableName)')
+  print('  void deleteRows(string login, string tableName, string startRow, string endRow)')
+  print('  void exportTable(string login, string tableName, string exportDir)')
+  print('  void flushTable(string login, string tableName, string startRow, string endRow, bool wait)')
+  print('   getDiskUsage(string login,  tables)')
+  print('   getLocalityGroups(string login, string tableName)')
+  print('  IteratorSetting getIteratorSetting(string login, string tableName, string iteratorName, IteratorScope scope)')
+  print('  string getMaxRow(string login, string tableName,  auths, string startRow, bool startInclusive, string endRow, bool endInclusive)')
+  print('   getTableProperties(string login, string tableName)')
+  print('  void importDirectory(string login, string tableName, string importDir, string failureDir, bool setTime)')
+  print('  void importTable(string login, string tableName, string importDir)')
+  print('   listSplits(string login, string tableName, i32 maxSplits)')
+  print('   listTables(string login)')
+  print('   listIterators(string login, string tableName)')
+  print('   listConstraints(string login, string tableName)')
+  print('  void mergeTablets(string login, string tableName, string startRow, string endRow)')
+  print('  void offlineTable(string login, string tableName, bool wait)')
+  print('  void onlineTable(string login, string tableName, bool wait)')
+  print('  void removeConstraint(string login, string tableName, i32 constraint)')
+  print('  void removeIterator(string login, string tableName, string iterName,  scopes)')
+  print('  void removeTableProperty(string login, string tableName, string property)')
+  print('  void renameTable(string login, string oldTableName, string newTableName)')
+  print('  void setLocalityGroups(string login, string tableName,  groups)')
+  print('  void setTableProperty(string login, string tableName, string property, string value)')
+  print('   splitRangeByTablets(string login, string tableName, Range range, i32 maxSplits)')
+  print('  bool tableExists(string login, string tableName)')
+  print('   tableIdMap(string login)')
+  print('  bool testTableClassLoad(string login, string tableName, string className, string asTypeName)')
+  print('  void pingTabletServer(string login, string tserver)')
+  print('   getActiveScans(string login, string tserver)')
+  print('   getActiveCompactions(string login, string tserver)')
+  print('   getSiteConfiguration(string login)')
+  print('   getSystemConfiguration(string login)')
+  print('   getTabletServers(string login)')
+  print('  void removeProperty(string login, string property)')
+  print('  void setProperty(string login, string property, string value)')
+  print('  bool testClassLoad(string login, string className, string asTypeName)')
+  print('  bool authenticateUser(string login, string user,  properties)')
+  print('  void changeUserAuthorizations(string login, string user,  authorizations)')
+  print('  void changeLocalUserPassword(string login, string user, string password)')
+  print('  void createLocalUser(string login, string user, string password)')
+  print('  void dropLocalUser(string login, string user)')
+  print('   getUserAuthorizations(string login, string user)')
+  print('  void grantSystemPermission(string login, string user, SystemPermission perm)')
+  print('  void grantTablePermission(string login, string user, string table, TablePermission perm)')
+  print('  bool hasSystemPermission(string login, string user, SystemPermission perm)')
+  print('  bool hasTablePermission(string login, string user, string table, TablePermission perm)')
+  print('   listLocalUsers(string login)')
+  print('  void revokeSystemPermission(string login, string user, SystemPermission perm)')
+  print('  void revokeTablePermission(string login, string user, string table, TablePermission perm)')
+  print('  void grantNamespacePermission(string login, string user, string namespaceName, NamespacePermission perm)')
+  print('  bool hasNamespacePermission(string login, string user, string namespaceName, NamespacePermission perm)')
+  print('  void revokeNamespacePermission(string login, string user, string namespaceName, NamespacePermission perm)')
+  print('  string createBatchScanner(string login, string tableName, BatchScanOptions options)')
+  print('  string createScanner(string login, string tableName, ScanOptions options)')
+  print('  bool hasNext(string scanner)')
+  print('  KeyValueAndPeek nextEntry(string scanner)')
+  print('  ScanResult nextK(string scanner, i32 k)')
+  print('  void closeScanner(string scanner)')
+  print('  void updateAndFlush(string login, string tableName,  cells)')
+  print('  string createWriter(string login, string tableName, WriterOptions opts)')
+  print('  void update(string writer,  cells)')
+  print('  void flush(string writer)')
+  print('  void closeWriter(string writer)')
+  print('  ConditionalStatus updateRowConditionally(string login, string tableName, string row, ConditionalUpdates updates)')
+  print('  string createConditionalWriter(string login, string tableName, ConditionalWriterOptions options)')
+  print('   updateRowsConditionally(string conditionalWriter,  updates)')
+  print('  void closeConditionalWriter(string conditionalWriter)')
+  print('  Range getRowRange(string row)')
+  print('  Key getFollowing(Key key, PartialKey part)')
+  print('  string systemNamespace()')
+  print('  string defaultNamespace()')
+  print('   listNamespaces(string login)')
+  print('  bool namespaceExists(string login, string namespaceName)')
+  print('  void createNamespace(string login, string namespaceName)')
+  print('  void deleteNamespace(string login, string namespaceName)')
+  print('  void renameNamespace(string login, string oldNamespaceName, string newNamespaceName)')
+  print('  void setNamespaceProperty(string login, string namespaceName, string property, string value)')
+  print('  void removeNamespaceProperty(string login, string namespaceName, string property)')
+  print('   getNamespaceProperties(string login, string namespaceName)')
+  print('   namespaceIdMap(string login)')
+  print('  void attachNamespaceIterator(string login, string namespaceName, IteratorSetting setting,  scopes)')
+  print('  void removeNamespaceIterator(string login, string namespaceName, string name,  scopes)')
+  print('  IteratorSetting getNamespaceIteratorSetting(string login, string namespaceName, string name, IteratorScope scope)')
+  print('   listNamespaceIterators(string login, string namespaceName)')
+  print('  void checkNamespaceIteratorConflicts(string login, string namespaceName, IteratorSetting setting,  scopes)')
+  print('  i32 addNamespaceConstraint(string login, string namespaceName, string constraintClassName)')
+  print('  void removeNamespaceConstraint(string login, string namespaceName, i32 id)')
+  print('   listNamespaceConstraints(string login, string namespaceName)')
+  print('  bool testNamespaceClassLoad(string login, string namespaceName, string className, string asTypeName)')
+  print('')
   sys.exit(0)
 
 pp = pprint.PrettyPrinter(indent = 2)
@@ -122,6 +146,7 @@
 port = 9090
 uri = ''
 framed = False
+ssl = False
 http = False
 argi = 1
 
@@ -150,13 +175,17 @@
   framed = True
   argi += 1
 
+if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':
+  ssl = True
+  argi += 1
+
 cmd = sys.argv[argi]
 args = sys.argv[argi+1:]
 
 if http:
   transport = THttpClient.THttpClient(host, port, uri)
 else:
-  socket = TSocket.TSocket(host, port)
+  socket = TSSLSocket.TSSLSocket(host, port, validate=False) if ssl else TSocket.TSocket(host, port)
   if framed:
     transport = TTransport.TFramedTransport(socket)
   else:
@@ -167,468 +196,606 @@
 
 if cmd == 'login':
   if len(args) != 2:
-    print 'login requires 2 args'
+    print('login requires 2 args')
     sys.exit(1)
   pp.pprint(client.login(args[0],eval(args[1]),))
 
 elif cmd == 'addConstraint':
   if len(args) != 3:
-    print 'addConstraint requires 3 args'
+    print('addConstraint requires 3 args')
     sys.exit(1)
   pp.pprint(client.addConstraint(args[0],args[1],args[2],))
 
 elif cmd == 'addSplits':
   if len(args) != 3:
-    print 'addSplits requires 3 args'
+    print('addSplits requires 3 args')
     sys.exit(1)
   pp.pprint(client.addSplits(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'attachIterator':
   if len(args) != 4:
-    print 'attachIterator requires 4 args'
+    print('attachIterator requires 4 args')
     sys.exit(1)
   pp.pprint(client.attachIterator(args[0],args[1],eval(args[2]),eval(args[3]),))
 
 elif cmd == 'checkIteratorConflicts':
   if len(args) != 4:
-    print 'checkIteratorConflicts requires 4 args'
+    print('checkIteratorConflicts requires 4 args')
     sys.exit(1)
   pp.pprint(client.checkIteratorConflicts(args[0],args[1],eval(args[2]),eval(args[3]),))
 
 elif cmd == 'clearLocatorCache':
   if len(args) != 2:
-    print 'clearLocatorCache requires 2 args'
+    print('clearLocatorCache requires 2 args')
     sys.exit(1)
   pp.pprint(client.clearLocatorCache(args[0],args[1],))
 
 elif cmd == 'cloneTable':
   if len(args) != 6:
-    print 'cloneTable requires 6 args'
+    print('cloneTable requires 6 args')
     sys.exit(1)
   pp.pprint(client.cloneTable(args[0],args[1],args[2],eval(args[3]),eval(args[4]),eval(args[5]),))
 
 elif cmd == 'compactTable':
   if len(args) != 8:
-    print 'compactTable requires 8 args'
+    print('compactTable requires 8 args')
     sys.exit(1)
   pp.pprint(client.compactTable(args[0],args[1],args[2],args[3],eval(args[4]),eval(args[5]),eval(args[6]),eval(args[7]),))
 
 elif cmd == 'cancelCompaction':
   if len(args) != 2:
-    print 'cancelCompaction requires 2 args'
+    print('cancelCompaction requires 2 args')
     sys.exit(1)
   pp.pprint(client.cancelCompaction(args[0],args[1],))
 
 elif cmd == 'createTable':
   if len(args) != 4:
-    print 'createTable requires 4 args'
+    print('createTable requires 4 args')
     sys.exit(1)
   pp.pprint(client.createTable(args[0],args[1],eval(args[2]),eval(args[3]),))
 
 elif cmd == 'deleteTable':
   if len(args) != 2:
-    print 'deleteTable requires 2 args'
+    print('deleteTable requires 2 args')
     sys.exit(1)
   pp.pprint(client.deleteTable(args[0],args[1],))
 
 elif cmd == 'deleteRows':
   if len(args) != 4:
-    print 'deleteRows requires 4 args'
+    print('deleteRows requires 4 args')
     sys.exit(1)
   pp.pprint(client.deleteRows(args[0],args[1],args[2],args[3],))
 
 elif cmd == 'exportTable':
   if len(args) != 3:
-    print 'exportTable requires 3 args'
+    print('exportTable requires 3 args')
     sys.exit(1)
   pp.pprint(client.exportTable(args[0],args[1],args[2],))
 
 elif cmd == 'flushTable':
   if len(args) != 5:
-    print 'flushTable requires 5 args'
+    print('flushTable requires 5 args')
     sys.exit(1)
   pp.pprint(client.flushTable(args[0],args[1],args[2],args[3],eval(args[4]),))
 
 elif cmd == 'getDiskUsage':
   if len(args) != 2:
-    print 'getDiskUsage requires 2 args'
+    print('getDiskUsage requires 2 args')
     sys.exit(1)
   pp.pprint(client.getDiskUsage(args[0],eval(args[1]),))
 
 elif cmd == 'getLocalityGroups':
   if len(args) != 2:
-    print 'getLocalityGroups requires 2 args'
+    print('getLocalityGroups requires 2 args')
     sys.exit(1)
   pp.pprint(client.getLocalityGroups(args[0],args[1],))
 
 elif cmd == 'getIteratorSetting':
   if len(args) != 4:
-    print 'getIteratorSetting requires 4 args'
+    print('getIteratorSetting requires 4 args')
     sys.exit(1)
   pp.pprint(client.getIteratorSetting(args[0],args[1],args[2],eval(args[3]),))
 
 elif cmd == 'getMaxRow':
   if len(args) != 7:
-    print 'getMaxRow requires 7 args'
+    print('getMaxRow requires 7 args')
     sys.exit(1)
   pp.pprint(client.getMaxRow(args[0],args[1],eval(args[2]),args[3],eval(args[4]),args[5],eval(args[6]),))
 
 elif cmd == 'getTableProperties':
   if len(args) != 2:
-    print 'getTableProperties requires 2 args'
+    print('getTableProperties requires 2 args')
     sys.exit(1)
   pp.pprint(client.getTableProperties(args[0],args[1],))
 
 elif cmd == 'importDirectory':
   if len(args) != 5:
-    print 'importDirectory requires 5 args'
+    print('importDirectory requires 5 args')
     sys.exit(1)
   pp.pprint(client.importDirectory(args[0],args[1],args[2],args[3],eval(args[4]),))
 
 elif cmd == 'importTable':
   if len(args) != 3:
-    print 'importTable requires 3 args'
+    print('importTable requires 3 args')
     sys.exit(1)
   pp.pprint(client.importTable(args[0],args[1],args[2],))
 
 elif cmd == 'listSplits':
   if len(args) != 3:
-    print 'listSplits requires 3 args'
+    print('listSplits requires 3 args')
     sys.exit(1)
   pp.pprint(client.listSplits(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'listTables':
   if len(args) != 1:
-    print 'listTables requires 1 args'
+    print('listTables requires 1 args')
     sys.exit(1)
   pp.pprint(client.listTables(args[0],))
 
 elif cmd == 'listIterators':
   if len(args) != 2:
-    print 'listIterators requires 2 args'
+    print('listIterators requires 2 args')
     sys.exit(1)
   pp.pprint(client.listIterators(args[0],args[1],))
 
 elif cmd == 'listConstraints':
   if len(args) != 2:
-    print 'listConstraints requires 2 args'
+    print('listConstraints requires 2 args')
     sys.exit(1)
   pp.pprint(client.listConstraints(args[0],args[1],))
 
 elif cmd == 'mergeTablets':
   if len(args) != 4:
-    print 'mergeTablets requires 4 args'
+    print('mergeTablets requires 4 args')
     sys.exit(1)
   pp.pprint(client.mergeTablets(args[0],args[1],args[2],args[3],))
 
 elif cmd == 'offlineTable':
   if len(args) != 3:
-    print 'offlineTable requires 3 args'
+    print('offlineTable requires 3 args')
     sys.exit(1)
   pp.pprint(client.offlineTable(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'onlineTable':
   if len(args) != 3:
-    print 'onlineTable requires 3 args'
+    print('onlineTable requires 3 args')
     sys.exit(1)
   pp.pprint(client.onlineTable(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'removeConstraint':
   if len(args) != 3:
-    print 'removeConstraint requires 3 args'
+    print('removeConstraint requires 3 args')
     sys.exit(1)
   pp.pprint(client.removeConstraint(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'removeIterator':
   if len(args) != 4:
-    print 'removeIterator requires 4 args'
+    print('removeIterator requires 4 args')
     sys.exit(1)
   pp.pprint(client.removeIterator(args[0],args[1],args[2],eval(args[3]),))
 
 elif cmd == 'removeTableProperty':
   if len(args) != 3:
-    print 'removeTableProperty requires 3 args'
+    print('removeTableProperty requires 3 args')
     sys.exit(1)
   pp.pprint(client.removeTableProperty(args[0],args[1],args[2],))
 
 elif cmd == 'renameTable':
   if len(args) != 3:
-    print 'renameTable requires 3 args'
+    print('renameTable requires 3 args')
     sys.exit(1)
   pp.pprint(client.renameTable(args[0],args[1],args[2],))
 
 elif cmd == 'setLocalityGroups':
   if len(args) != 3:
-    print 'setLocalityGroups requires 3 args'
+    print('setLocalityGroups requires 3 args')
     sys.exit(1)
   pp.pprint(client.setLocalityGroups(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'setTableProperty':
   if len(args) != 4:
-    print 'setTableProperty requires 4 args'
+    print('setTableProperty requires 4 args')
     sys.exit(1)
   pp.pprint(client.setTableProperty(args[0],args[1],args[2],args[3],))
 
 elif cmd == 'splitRangeByTablets':
   if len(args) != 4:
-    print 'splitRangeByTablets requires 4 args'
+    print('splitRangeByTablets requires 4 args')
     sys.exit(1)
   pp.pprint(client.splitRangeByTablets(args[0],args[1],eval(args[2]),eval(args[3]),))
 
 elif cmd == 'tableExists':
   if len(args) != 2:
-    print 'tableExists requires 2 args'
+    print('tableExists requires 2 args')
     sys.exit(1)
   pp.pprint(client.tableExists(args[0],args[1],))
 
 elif cmd == 'tableIdMap':
   if len(args) != 1:
-    print 'tableIdMap requires 1 args'
+    print('tableIdMap requires 1 args')
     sys.exit(1)
   pp.pprint(client.tableIdMap(args[0],))
 
 elif cmd == 'testTableClassLoad':
   if len(args) != 4:
-    print 'testTableClassLoad requires 4 args'
+    print('testTableClassLoad requires 4 args')
     sys.exit(1)
   pp.pprint(client.testTableClassLoad(args[0],args[1],args[2],args[3],))
 
 elif cmd == 'pingTabletServer':
   if len(args) != 2:
-    print 'pingTabletServer requires 2 args'
+    print('pingTabletServer requires 2 args')
     sys.exit(1)
   pp.pprint(client.pingTabletServer(args[0],args[1],))
 
 elif cmd == 'getActiveScans':
   if len(args) != 2:
-    print 'getActiveScans requires 2 args'
+    print('getActiveScans requires 2 args')
     sys.exit(1)
   pp.pprint(client.getActiveScans(args[0],args[1],))
 
 elif cmd == 'getActiveCompactions':
   if len(args) != 2:
-    print 'getActiveCompactions requires 2 args'
+    print('getActiveCompactions requires 2 args')
     sys.exit(1)
   pp.pprint(client.getActiveCompactions(args[0],args[1],))
 
 elif cmd == 'getSiteConfiguration':
   if len(args) != 1:
-    print 'getSiteConfiguration requires 1 args'
+    print('getSiteConfiguration requires 1 args')
     sys.exit(1)
   pp.pprint(client.getSiteConfiguration(args[0],))
 
 elif cmd == 'getSystemConfiguration':
   if len(args) != 1:
-    print 'getSystemConfiguration requires 1 args'
+    print('getSystemConfiguration requires 1 args')
     sys.exit(1)
   pp.pprint(client.getSystemConfiguration(args[0],))
 
 elif cmd == 'getTabletServers':
   if len(args) != 1:
-    print 'getTabletServers requires 1 args'
+    print('getTabletServers requires 1 args')
     sys.exit(1)
   pp.pprint(client.getTabletServers(args[0],))
 
 elif cmd == 'removeProperty':
   if len(args) != 2:
-    print 'removeProperty requires 2 args'
+    print('removeProperty requires 2 args')
     sys.exit(1)
   pp.pprint(client.removeProperty(args[0],args[1],))
 
 elif cmd == 'setProperty':
   if len(args) != 3:
-    print 'setProperty requires 3 args'
+    print('setProperty requires 3 args')
     sys.exit(1)
   pp.pprint(client.setProperty(args[0],args[1],args[2],))
 
 elif cmd == 'testClassLoad':
   if len(args) != 3:
-    print 'testClassLoad requires 3 args'
+    print('testClassLoad requires 3 args')
     sys.exit(1)
   pp.pprint(client.testClassLoad(args[0],args[1],args[2],))
 
 elif cmd == 'authenticateUser':
   if len(args) != 3:
-    print 'authenticateUser requires 3 args'
+    print('authenticateUser requires 3 args')
     sys.exit(1)
   pp.pprint(client.authenticateUser(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'changeUserAuthorizations':
   if len(args) != 3:
-    print 'changeUserAuthorizations requires 3 args'
+    print('changeUserAuthorizations requires 3 args')
     sys.exit(1)
   pp.pprint(client.changeUserAuthorizations(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'changeLocalUserPassword':
   if len(args) != 3:
-    print 'changeLocalUserPassword requires 3 args'
+    print('changeLocalUserPassword requires 3 args')
     sys.exit(1)
   pp.pprint(client.changeLocalUserPassword(args[0],args[1],args[2],))
 
 elif cmd == 'createLocalUser':
   if len(args) != 3:
-    print 'createLocalUser requires 3 args'
+    print('createLocalUser requires 3 args')
     sys.exit(1)
   pp.pprint(client.createLocalUser(args[0],args[1],args[2],))
 
 elif cmd == 'dropLocalUser':
   if len(args) != 2:
-    print 'dropLocalUser requires 2 args'
+    print('dropLocalUser requires 2 args')
     sys.exit(1)
   pp.pprint(client.dropLocalUser(args[0],args[1],))
 
 elif cmd == 'getUserAuthorizations':
   if len(args) != 2:
-    print 'getUserAuthorizations requires 2 args'
+    print('getUserAuthorizations requires 2 args')
     sys.exit(1)
   pp.pprint(client.getUserAuthorizations(args[0],args[1],))
 
 elif cmd == 'grantSystemPermission':
   if len(args) != 3:
-    print 'grantSystemPermission requires 3 args'
+    print('grantSystemPermission requires 3 args')
     sys.exit(1)
   pp.pprint(client.grantSystemPermission(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'grantTablePermission':
   if len(args) != 4:
-    print 'grantTablePermission requires 4 args'
+    print('grantTablePermission requires 4 args')
     sys.exit(1)
   pp.pprint(client.grantTablePermission(args[0],args[1],args[2],eval(args[3]),))
 
 elif cmd == 'hasSystemPermission':
   if len(args) != 3:
-    print 'hasSystemPermission requires 3 args'
+    print('hasSystemPermission requires 3 args')
     sys.exit(1)
   pp.pprint(client.hasSystemPermission(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'hasTablePermission':
   if len(args) != 4:
-    print 'hasTablePermission requires 4 args'
+    print('hasTablePermission requires 4 args')
     sys.exit(1)
   pp.pprint(client.hasTablePermission(args[0],args[1],args[2],eval(args[3]),))
 
 elif cmd == 'listLocalUsers':
   if len(args) != 1:
-    print 'listLocalUsers requires 1 args'
+    print('listLocalUsers requires 1 args')
     sys.exit(1)
   pp.pprint(client.listLocalUsers(args[0],))
 
 elif cmd == 'revokeSystemPermission':
   if len(args) != 3:
-    print 'revokeSystemPermission requires 3 args'
+    print('revokeSystemPermission requires 3 args')
     sys.exit(1)
   pp.pprint(client.revokeSystemPermission(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'revokeTablePermission':
   if len(args) != 4:
-    print 'revokeTablePermission requires 4 args'
+    print('revokeTablePermission requires 4 args')
     sys.exit(1)
   pp.pprint(client.revokeTablePermission(args[0],args[1],args[2],eval(args[3]),))
 
+elif cmd == 'grantNamespacePermission':
+  if len(args) != 4:
+    print('grantNamespacePermission requires 4 args')
+    sys.exit(1)
+  pp.pprint(client.grantNamespacePermission(args[0],args[1],args[2],eval(args[3]),))
+
+elif cmd == 'hasNamespacePermission':
+  if len(args) != 4:
+    print('hasNamespacePermission requires 4 args')
+    sys.exit(1)
+  pp.pprint(client.hasNamespacePermission(args[0],args[1],args[2],eval(args[3]),))
+
+elif cmd == 'revokeNamespacePermission':
+  if len(args) != 4:
+    print('revokeNamespacePermission requires 4 args')
+    sys.exit(1)
+  pp.pprint(client.revokeNamespacePermission(args[0],args[1],args[2],eval(args[3]),))
+
 elif cmd == 'createBatchScanner':
   if len(args) != 3:
-    print 'createBatchScanner requires 3 args'
+    print('createBatchScanner requires 3 args')
     sys.exit(1)
   pp.pprint(client.createBatchScanner(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'createScanner':
   if len(args) != 3:
-    print 'createScanner requires 3 args'
+    print('createScanner requires 3 args')
     sys.exit(1)
   pp.pprint(client.createScanner(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'hasNext':
   if len(args) != 1:
-    print 'hasNext requires 1 args'
+    print('hasNext requires 1 args')
     sys.exit(1)
   pp.pprint(client.hasNext(args[0],))
 
 elif cmd == 'nextEntry':
   if len(args) != 1:
-    print 'nextEntry requires 1 args'
+    print('nextEntry requires 1 args')
     sys.exit(1)
   pp.pprint(client.nextEntry(args[0],))
 
 elif cmd == 'nextK':
   if len(args) != 2:
-    print 'nextK requires 2 args'
+    print('nextK requires 2 args')
     sys.exit(1)
   pp.pprint(client.nextK(args[0],eval(args[1]),))
 
 elif cmd == 'closeScanner':
   if len(args) != 1:
-    print 'closeScanner requires 1 args'
+    print('closeScanner requires 1 args')
     sys.exit(1)
   pp.pprint(client.closeScanner(args[0],))
 
 elif cmd == 'updateAndFlush':
   if len(args) != 3:
-    print 'updateAndFlush requires 3 args'
+    print('updateAndFlush requires 3 args')
     sys.exit(1)
   pp.pprint(client.updateAndFlush(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'createWriter':
   if len(args) != 3:
-    print 'createWriter requires 3 args'
+    print('createWriter requires 3 args')
     sys.exit(1)
   pp.pprint(client.createWriter(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'update':
   if len(args) != 2:
-    print 'update requires 2 args'
+    print('update requires 2 args')
     sys.exit(1)
   pp.pprint(client.update(args[0],eval(args[1]),))
 
 elif cmd == 'flush':
   if len(args) != 1:
-    print 'flush requires 1 args'
+    print('flush requires 1 args')
     sys.exit(1)
   pp.pprint(client.flush(args[0],))
 
 elif cmd == 'closeWriter':
   if len(args) != 1:
-    print 'closeWriter requires 1 args'
+    print('closeWriter requires 1 args')
     sys.exit(1)
   pp.pprint(client.closeWriter(args[0],))
 
 elif cmd == 'updateRowConditionally':
   if len(args) != 4:
-    print 'updateRowConditionally requires 4 args'
+    print('updateRowConditionally requires 4 args')
     sys.exit(1)
   pp.pprint(client.updateRowConditionally(args[0],args[1],args[2],eval(args[3]),))
 
 elif cmd == 'createConditionalWriter':
   if len(args) != 3:
-    print 'createConditionalWriter requires 3 args'
+    print('createConditionalWriter requires 3 args')
     sys.exit(1)
   pp.pprint(client.createConditionalWriter(args[0],args[1],eval(args[2]),))
 
 elif cmd == 'updateRowsConditionally':
   if len(args) != 2:
-    print 'updateRowsConditionally requires 2 args'
+    print('updateRowsConditionally requires 2 args')
     sys.exit(1)
   pp.pprint(client.updateRowsConditionally(args[0],eval(args[1]),))
 
 elif cmd == 'closeConditionalWriter':
   if len(args) != 1:
-    print 'closeConditionalWriter requires 1 args'
+    print('closeConditionalWriter requires 1 args')
     sys.exit(1)
   pp.pprint(client.closeConditionalWriter(args[0],))
 
 elif cmd == 'getRowRange':
   if len(args) != 1:
-    print 'getRowRange requires 1 args'
+    print('getRowRange requires 1 args')
     sys.exit(1)
   pp.pprint(client.getRowRange(args[0],))
 
 elif cmd == 'getFollowing':
   if len(args) != 2:
-    print 'getFollowing requires 2 args'
+    print('getFollowing requires 2 args')
     sys.exit(1)
   pp.pprint(client.getFollowing(eval(args[0]),eval(args[1]),))
 
+elif cmd == 'systemNamespace':
+  if len(args) != 0:
+    print('systemNamespace requires 0 args')
+    sys.exit(1)
+  pp.pprint(client.systemNamespace())
+
+elif cmd == 'defaultNamespace':
+  if len(args) != 0:
+    print('defaultNamespace requires 0 args')
+    sys.exit(1)
+  pp.pprint(client.defaultNamespace())
+
+elif cmd == 'listNamespaces':
+  if len(args) != 1:
+    print('listNamespaces requires 1 args')
+    sys.exit(1)
+  pp.pprint(client.listNamespaces(args[0],))
+
+elif cmd == 'namespaceExists':
+  if len(args) != 2:
+    print('namespaceExists requires 2 args')
+    sys.exit(1)
+  pp.pprint(client.namespaceExists(args[0],args[1],))
+
+elif cmd == 'createNamespace':
+  if len(args) != 2:
+    print('createNamespace requires 2 args')
+    sys.exit(1)
+  pp.pprint(client.createNamespace(args[0],args[1],))
+
+elif cmd == 'deleteNamespace':
+  if len(args) != 2:
+    print('deleteNamespace requires 2 args')
+    sys.exit(1)
+  pp.pprint(client.deleteNamespace(args[0],args[1],))
+
+elif cmd == 'renameNamespace':
+  if len(args) != 3:
+    print('renameNamespace requires 3 args')
+    sys.exit(1)
+  pp.pprint(client.renameNamespace(args[0],args[1],args[2],))
+
+elif cmd == 'setNamespaceProperty':
+  if len(args) != 4:
+    print('setNamespaceProperty requires 4 args')
+    sys.exit(1)
+  pp.pprint(client.setNamespaceProperty(args[0],args[1],args[2],args[3],))
+
+elif cmd == 'removeNamespaceProperty':
+  if len(args) != 3:
+    print('removeNamespaceProperty requires 3 args')
+    sys.exit(1)
+  pp.pprint(client.removeNamespaceProperty(args[0],args[1],args[2],))
+
+elif cmd == 'getNamespaceProperties':
+  if len(args) != 2:
+    print('getNamespaceProperties requires 2 args')
+    sys.exit(1)
+  pp.pprint(client.getNamespaceProperties(args[0],args[1],))
+
+elif cmd == 'namespaceIdMap':
+  if len(args) != 1:
+    print('namespaceIdMap requires 1 args')
+    sys.exit(1)
+  pp.pprint(client.namespaceIdMap(args[0],))
+
+elif cmd == 'attachNamespaceIterator':
+  if len(args) != 4:
+    print('attachNamespaceIterator requires 4 args')
+    sys.exit(1)
+  pp.pprint(client.attachNamespaceIterator(args[0],args[1],eval(args[2]),eval(args[3]),))
+
+elif cmd == 'removeNamespaceIterator':
+  if len(args) != 4:
+    print('removeNamespaceIterator requires 4 args')
+    sys.exit(1)
+  pp.pprint(client.removeNamespaceIterator(args[0],args[1],args[2],eval(args[3]),))
+
+elif cmd == 'getNamespaceIteratorSetting':
+  if len(args) != 4:
+    print('getNamespaceIteratorSetting requires 4 args')
+    sys.exit(1)
+  pp.pprint(client.getNamespaceIteratorSetting(args[0],args[1],args[2],eval(args[3]),))
+
+elif cmd == 'listNamespaceIterators':
+  if len(args) != 2:
+    print('listNamespaceIterators requires 2 args')
+    sys.exit(1)
+  pp.pprint(client.listNamespaceIterators(args[0],args[1],))
+
+elif cmd == 'checkNamespaceIteratorConflicts':
+  if len(args) != 4:
+    print('checkNamespaceIteratorConflicts requires 4 args')
+    sys.exit(1)
+  pp.pprint(client.checkNamespaceIteratorConflicts(args[0],args[1],eval(args[2]),eval(args[3]),))
+
+elif cmd == 'addNamespaceConstraint':
+  if len(args) != 3:
+    print('addNamespaceConstraint requires 3 args')
+    sys.exit(1)
+  pp.pprint(client.addNamespaceConstraint(args[0],args[1],args[2],))
+
+elif cmd == 'removeNamespaceConstraint':
+  if len(args) != 3:
+    print('removeNamespaceConstraint requires 3 args')
+    sys.exit(1)
+  pp.pprint(client.removeNamespaceConstraint(args[0],args[1],eval(args[2]),))
+
+elif cmd == 'listNamespaceConstraints':
+  if len(args) != 2:
+    print('listNamespaceConstraints requires 2 args')
+    sys.exit(1)
+  pp.pprint(client.listNamespaceConstraints(args[0],args[1],))
+
+elif cmd == 'testNamespaceClassLoad':
+  if len(args) != 4:
+    print('testNamespaceClassLoad requires 4 args')
+    sys.exit(1)
+  pp.pprint(client.testNamespaceClassLoad(args[0],args[1],args[2],args[3],))
+
 else:
-  print 'Unrecognized method %s' % cmd
+  print('Unrecognized method %s' % cmd)
   sys.exit(1)
 
 transport.close()
diff --git a/src/main/python/AccumuloProxy.py b/src/main/python/AccumuloProxy.py
index 2805fff..19bd257 100644
--- a/src/main/python/AccumuloProxy.py
+++ b/src/main/python/AccumuloProxy.py
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Autogenerated by Thrift Compiler (0.9.1)
+# Autogenerated by Thrift Compiler (0.9.3)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
@@ -21,6 +21,7 @@
 #
 
 from thrift.Thrift import TType, TMessageType, TException, TApplicationException
+import logging
 from ttypes import *
 from thrift.Thrift import TProcessor
 from thrift.transport import TTransport
@@ -573,6 +574,36 @@
     """
     pass
 
+  def grantNamespacePermission(self, login, user, namespaceName, perm):
+    """
+    Parameters:
+     - login
+     - user
+     - namespaceName
+     - perm
+    """
+    pass
+
+  def hasNamespacePermission(self, login, user, namespaceName, perm):
+    """
+    Parameters:
+     - login
+     - user
+     - namespaceName
+     - perm
+    """
+    pass
+
+  def revokeNamespacePermission(self, login, user, namespaceName, perm):
+    """
+    Parameters:
+     - login
+     - user
+     - namespaceName
+     - perm
+    """
+    pass
+
   def createBatchScanner(self, login, tableName, options):
     """
     Parameters:
@@ -709,6 +740,170 @@
     """
     pass
 
+  def systemNamespace(self):
+    pass
+
+  def defaultNamespace(self):
+    pass
+
+  def listNamespaces(self, login):
+    """
+    Parameters:
+     - login
+    """
+    pass
+
+  def namespaceExists(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    pass
+
+  def createNamespace(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    pass
+
+  def deleteNamespace(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    pass
+
+  def renameNamespace(self, login, oldNamespaceName, newNamespaceName):
+    """
+    Parameters:
+     - login
+     - oldNamespaceName
+     - newNamespaceName
+    """
+    pass
+
+  def setNamespaceProperty(self, login, namespaceName, property, value):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - property
+     - value
+    """
+    pass
+
+  def removeNamespaceProperty(self, login, namespaceName, property):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - property
+    """
+    pass
+
+  def getNamespaceProperties(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    pass
+
+  def namespaceIdMap(self, login):
+    """
+    Parameters:
+     - login
+    """
+    pass
+
+  def attachNamespaceIterator(self, login, namespaceName, setting, scopes):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - setting
+     - scopes
+    """
+    pass
+
+  def removeNamespaceIterator(self, login, namespaceName, name, scopes):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - name
+     - scopes
+    """
+    pass
+
+  def getNamespaceIteratorSetting(self, login, namespaceName, name, scope):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - name
+     - scope
+    """
+    pass
+
+  def listNamespaceIterators(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    pass
+
+  def checkNamespaceIteratorConflicts(self, login, namespaceName, setting, scopes):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - setting
+     - scopes
+    """
+    pass
+
+  def addNamespaceConstraint(self, login, namespaceName, constraintClassName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - constraintClassName
+    """
+    pass
+
+  def removeNamespaceConstraint(self, login, namespaceName, id):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - id
+    """
+    pass
+
+  def listNamespaceConstraints(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    pass
+
+  def testNamespaceClassLoad(self, login, namespaceName, className, asTypeName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - className
+     - asTypeName
+    """
+    pass
+
 
 class Client(Iface):
   def __init__(self, iprot, oprot=None):
@@ -736,20 +931,21 @@
     self._oprot.trans.flush()
 
   def recv_login(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = login_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch2 is not None:
       raise result.ouch2
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "login failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "login failed: unknown result")
 
   def addConstraint(self, login, tableName, constraintClassName):
     """
@@ -772,15 +968,16 @@
     self._oprot.trans.flush()
 
   def recv_addConstraint(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = addConstraint_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -789,7 +986,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "addConstraint failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "addConstraint failed: unknown result")
 
   def addSplits(self, login, tableName, splits):
     """
@@ -812,15 +1009,16 @@
     self._oprot.trans.flush()
 
   def recv_addSplits(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = addSplits_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -852,15 +1050,16 @@
     self._oprot.trans.flush()
 
   def recv_attachIterator(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = attachIterator_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -892,15 +1091,16 @@
     self._oprot.trans.flush()
 
   def recv_checkIteratorConflicts(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = checkIteratorConflicts_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -928,15 +1128,16 @@
     self._oprot.trans.flush()
 
   def recv_clearLocatorCache(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = clearLocatorCache_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     return
@@ -968,15 +1169,16 @@
     self._oprot.trans.flush()
 
   def recv_cloneTable(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = cloneTable_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1018,15 +1220,16 @@
     self._oprot.trans.flush()
 
   def recv_compactTable(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = compactTable_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1054,15 +1257,16 @@
     self._oprot.trans.flush()
 
   def recv_cancelCompaction(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = cancelCompaction_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1094,15 +1298,16 @@
     self._oprot.trans.flush()
 
   def recv_createTable(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = createTable_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1130,15 +1335,16 @@
     self._oprot.trans.flush()
 
   def recv_deleteTable(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = deleteTable_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1170,15 +1376,16 @@
     self._oprot.trans.flush()
 
   def recv_deleteRows(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = deleteRows_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1208,15 +1415,16 @@
     self._oprot.trans.flush()
 
   def recv_exportTable(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = exportTable_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1250,15 +1458,16 @@
     self._oprot.trans.flush()
 
   def recv_flushTable(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = flushTable_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1286,15 +1495,16 @@
     self._oprot.trans.flush()
 
   def recv_getDiskUsage(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getDiskUsage_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -1303,7 +1513,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getDiskUsage failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getDiskUsage failed: unknown result")
 
   def getLocalityGroups(self, login, tableName):
     """
@@ -1324,15 +1534,16 @@
     self._oprot.trans.flush()
 
   def recv_getLocalityGroups(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getLocalityGroups_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -1341,7 +1552,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getLocalityGroups failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getLocalityGroups failed: unknown result")
 
   def getIteratorSetting(self, login, tableName, iteratorName, scope):
     """
@@ -1366,15 +1577,16 @@
     self._oprot.trans.flush()
 
   def recv_getIteratorSetting(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getIteratorSetting_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -1383,7 +1595,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getIteratorSetting failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getIteratorSetting failed: unknown result")
 
   def getMaxRow(self, login, tableName, auths, startRow, startInclusive, endRow, endInclusive):
     """
@@ -1414,15 +1626,16 @@
     self._oprot.trans.flush()
 
   def recv_getMaxRow(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getMaxRow_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -1431,7 +1644,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getMaxRow failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getMaxRow failed: unknown result")
 
   def getTableProperties(self, login, tableName):
     """
@@ -1452,15 +1665,16 @@
     self._oprot.trans.flush()
 
   def recv_getTableProperties(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getTableProperties_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -1469,7 +1683,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getTableProperties failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getTableProperties failed: unknown result")
 
   def importDirectory(self, login, tableName, importDir, failureDir, setTime):
     """
@@ -1496,15 +1710,16 @@
     self._oprot.trans.flush()
 
   def recv_importDirectory(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = importDirectory_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch3 is not None:
@@ -1534,15 +1749,16 @@
     self._oprot.trans.flush()
 
   def recv_importTable(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = importTable_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1572,15 +1788,16 @@
     self._oprot.trans.flush()
 
   def recv_listSplits(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = listSplits_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -1589,7 +1806,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "listSplits failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "listSplits failed: unknown result")
 
   def listTables(self, login):
     """
@@ -1608,18 +1825,19 @@
     self._oprot.trans.flush()
 
   def recv_listTables(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = listTables_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "listTables failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "listTables failed: unknown result")
 
   def listIterators(self, login, tableName):
     """
@@ -1640,15 +1858,16 @@
     self._oprot.trans.flush()
 
   def recv_listIterators(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = listIterators_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -1657,7 +1876,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "listIterators failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "listIterators failed: unknown result")
 
   def listConstraints(self, login, tableName):
     """
@@ -1678,15 +1897,16 @@
     self._oprot.trans.flush()
 
   def recv_listConstraints(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = listConstraints_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -1695,7 +1915,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "listConstraints failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "listConstraints failed: unknown result")
 
   def mergeTablets(self, login, tableName, startRow, endRow):
     """
@@ -1720,15 +1940,16 @@
     self._oprot.trans.flush()
 
   def recv_mergeTablets(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = mergeTablets_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1758,15 +1979,16 @@
     self._oprot.trans.flush()
 
   def recv_offlineTable(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = offlineTable_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1796,15 +2018,16 @@
     self._oprot.trans.flush()
 
   def recv_onlineTable(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = onlineTable_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1834,15 +2057,16 @@
     self._oprot.trans.flush()
 
   def recv_removeConstraint(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = removeConstraint_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1874,15 +2098,16 @@
     self._oprot.trans.flush()
 
   def recv_removeIterator(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = removeIterator_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1912,15 +2137,16 @@
     self._oprot.trans.flush()
 
   def recv_removeTableProperty(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = removeTableProperty_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1950,15 +2176,16 @@
     self._oprot.trans.flush()
 
   def recv_renameTable(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = renameTable_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -1990,15 +2217,16 @@
     self._oprot.trans.flush()
 
   def recv_setLocalityGroups(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = setLocalityGroups_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2030,15 +2258,16 @@
     self._oprot.trans.flush()
 
   def recv_setTableProperty(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = setTableProperty_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2070,15 +2299,16 @@
     self._oprot.trans.flush()
 
   def recv_splitRangeByTablets(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = splitRangeByTablets_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -2087,7 +2317,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "splitRangeByTablets failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "splitRangeByTablets failed: unknown result")
 
   def tableExists(self, login, tableName):
     """
@@ -2108,18 +2338,19 @@
     self._oprot.trans.flush()
 
   def recv_tableExists(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = tableExists_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "tableExists failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "tableExists failed: unknown result")
 
   def tableIdMap(self, login):
     """
@@ -2138,18 +2369,19 @@
     self._oprot.trans.flush()
 
   def recv_tableIdMap(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = tableIdMap_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "tableIdMap failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "tableIdMap failed: unknown result")
 
   def testTableClassLoad(self, login, tableName, className, asTypeName):
     """
@@ -2174,15 +2406,16 @@
     self._oprot.trans.flush()
 
   def recv_testTableClassLoad(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = testTableClassLoad_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -2191,7 +2424,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "testTableClassLoad failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "testTableClassLoad failed: unknown result")
 
   def pingTabletServer(self, login, tserver):
     """
@@ -2212,15 +2445,16 @@
     self._oprot.trans.flush()
 
   def recv_pingTabletServer(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = pingTabletServer_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2246,22 +2480,23 @@
     self._oprot.trans.flush()
 
   def recv_getActiveScans(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getActiveScans_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
       raise result.ouch2
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getActiveScans failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getActiveScans failed: unknown result")
 
   def getActiveCompactions(self, login, tserver):
     """
@@ -2282,22 +2517,23 @@
     self._oprot.trans.flush()
 
   def recv_getActiveCompactions(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getActiveCompactions_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
       raise result.ouch2
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getActiveCompactions failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getActiveCompactions failed: unknown result")
 
   def getSiteConfiguration(self, login):
     """
@@ -2316,22 +2552,23 @@
     self._oprot.trans.flush()
 
   def recv_getSiteConfiguration(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getSiteConfiguration_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
       raise result.ouch2
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getSiteConfiguration failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getSiteConfiguration failed: unknown result")
 
   def getSystemConfiguration(self, login):
     """
@@ -2350,22 +2587,23 @@
     self._oprot.trans.flush()
 
   def recv_getSystemConfiguration(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getSystemConfiguration_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
       raise result.ouch2
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getSystemConfiguration failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getSystemConfiguration failed: unknown result")
 
   def getTabletServers(self, login):
     """
@@ -2384,18 +2622,19 @@
     self._oprot.trans.flush()
 
   def recv_getTabletServers(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getTabletServers_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getTabletServers failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getTabletServers failed: unknown result")
 
   def removeProperty(self, login, property):
     """
@@ -2416,15 +2655,16 @@
     self._oprot.trans.flush()
 
   def recv_removeProperty(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = removeProperty_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2452,15 +2692,16 @@
     self._oprot.trans.flush()
 
   def recv_setProperty(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = setProperty_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2488,22 +2729,23 @@
     self._oprot.trans.flush()
 
   def recv_testClassLoad(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = testClassLoad_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
       raise result.ouch2
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "testClassLoad failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "testClassLoad failed: unknown result")
 
   def authenticateUser(self, login, user, properties):
     """
@@ -2526,22 +2768,23 @@
     self._oprot.trans.flush()
 
   def recv_authenticateUser(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = authenticateUser_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
       raise result.ouch2
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "authenticateUser failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "authenticateUser failed: unknown result")
 
   def changeUserAuthorizations(self, login, user, authorizations):
     """
@@ -2564,15 +2807,16 @@
     self._oprot.trans.flush()
 
   def recv_changeUserAuthorizations(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = changeUserAuthorizations_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2600,15 +2844,16 @@
     self._oprot.trans.flush()
 
   def recv_changeLocalUserPassword(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = changeLocalUserPassword_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2636,15 +2881,16 @@
     self._oprot.trans.flush()
 
   def recv_createLocalUser(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = createLocalUser_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2670,15 +2916,16 @@
     self._oprot.trans.flush()
 
   def recv_dropLocalUser(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = dropLocalUser_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2704,22 +2951,23 @@
     self._oprot.trans.flush()
 
   def recv_getUserAuthorizations(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getUserAuthorizations_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
       raise result.ouch2
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getUserAuthorizations failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getUserAuthorizations failed: unknown result")
 
   def grantSystemPermission(self, login, user, perm):
     """
@@ -2742,15 +2990,16 @@
     self._oprot.trans.flush()
 
   def recv_grantSystemPermission(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = grantSystemPermission_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2780,15 +3029,16 @@
     self._oprot.trans.flush()
 
   def recv_grantTablePermission(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = grantTablePermission_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2818,22 +3068,23 @@
     self._oprot.trans.flush()
 
   def recv_hasSystemPermission(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = hasSystemPermission_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
       raise result.ouch2
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "hasSystemPermission failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "hasSystemPermission failed: unknown result")
 
   def hasTablePermission(self, login, user, table, perm):
     """
@@ -2858,15 +3109,16 @@
     self._oprot.trans.flush()
 
   def recv_hasTablePermission(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = hasTablePermission_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -2875,7 +3127,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "hasTablePermission failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "hasTablePermission failed: unknown result")
 
   def listLocalUsers(self, login):
     """
@@ -2894,15 +3146,16 @@
     self._oprot.trans.flush()
 
   def recv_listLocalUsers(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = listLocalUsers_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -2911,7 +3164,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "listLocalUsers failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "listLocalUsers failed: unknown result")
 
   def revokeSystemPermission(self, login, user, perm):
     """
@@ -2934,15 +3187,16 @@
     self._oprot.trans.flush()
 
   def recv_revokeSystemPermission(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = revokeSystemPermission_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2972,15 +3226,16 @@
     self._oprot.trans.flush()
 
   def recv_revokeTablePermission(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = revokeTablePermission_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -2989,6 +3244,125 @@
       raise result.ouch3
     return
 
+  def grantNamespacePermission(self, login, user, namespaceName, perm):
+    """
+    Parameters:
+     - login
+     - user
+     - namespaceName
+     - perm
+    """
+    self.send_grantNamespacePermission(login, user, namespaceName, perm)
+    self.recv_grantNamespacePermission()
+
+  def send_grantNamespacePermission(self, login, user, namespaceName, perm):
+    self._oprot.writeMessageBegin('grantNamespacePermission', TMessageType.CALL, self._seqid)
+    args = grantNamespacePermission_args()
+    args.login = login
+    args.user = user
+    args.namespaceName = namespaceName
+    args.perm = perm
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_grantNamespacePermission(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = grantNamespacePermission_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    return
+
+  def hasNamespacePermission(self, login, user, namespaceName, perm):
+    """
+    Parameters:
+     - login
+     - user
+     - namespaceName
+     - perm
+    """
+    self.send_hasNamespacePermission(login, user, namespaceName, perm)
+    return self.recv_hasNamespacePermission()
+
+  def send_hasNamespacePermission(self, login, user, namespaceName, perm):
+    self._oprot.writeMessageBegin('hasNamespacePermission', TMessageType.CALL, self._seqid)
+    args = hasNamespacePermission_args()
+    args.login = login
+    args.user = user
+    args.namespaceName = namespaceName
+    args.perm = perm
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_hasNamespacePermission(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = hasNamespacePermission_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "hasNamespacePermission failed: unknown result")
+
+  def revokeNamespacePermission(self, login, user, namespaceName, perm):
+    """
+    Parameters:
+     - login
+     - user
+     - namespaceName
+     - perm
+    """
+    self.send_revokeNamespacePermission(login, user, namespaceName, perm)
+    self.recv_revokeNamespacePermission()
+
+  def send_revokeNamespacePermission(self, login, user, namespaceName, perm):
+    self._oprot.writeMessageBegin('revokeNamespacePermission', TMessageType.CALL, self._seqid)
+    args = revokeNamespacePermission_args()
+    args.login = login
+    args.user = user
+    args.namespaceName = namespaceName
+    args.perm = perm
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_revokeNamespacePermission(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = revokeNamespacePermission_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    return
+
   def createBatchScanner(self, login, tableName, options):
     """
     Parameters:
@@ -3010,15 +3384,16 @@
     self._oprot.trans.flush()
 
   def recv_createBatchScanner(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = createBatchScanner_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -3027,7 +3402,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "createBatchScanner failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "createBatchScanner failed: unknown result")
 
   def createScanner(self, login, tableName, options):
     """
@@ -3050,15 +3425,16 @@
     self._oprot.trans.flush()
 
   def recv_createScanner(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = createScanner_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -3067,7 +3443,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "createScanner failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "createScanner failed: unknown result")
 
   def hasNext(self, scanner):
     """
@@ -3086,20 +3462,21 @@
     self._oprot.trans.flush()
 
   def recv_hasNext(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = hasNext_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
       raise result.ouch1
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "hasNext failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "hasNext failed: unknown result")
 
   def nextEntry(self, scanner):
     """
@@ -3118,15 +3495,16 @@
     self._oprot.trans.flush()
 
   def recv_nextEntry(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = nextEntry_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -3135,7 +3513,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "nextEntry failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "nextEntry failed: unknown result")
 
   def nextK(self, scanner, k):
     """
@@ -3156,15 +3534,16 @@
     self._oprot.trans.flush()
 
   def recv_nextK(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = nextK_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -3173,7 +3552,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "nextK failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "nextK failed: unknown result")
 
   def closeScanner(self, scanner):
     """
@@ -3192,15 +3571,16 @@
     self._oprot.trans.flush()
 
   def recv_closeScanner(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = closeScanner_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     return
@@ -3226,15 +3606,16 @@
     self._oprot.trans.flush()
 
   def recv_updateAndFlush(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = updateAndFlush_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.outch1 is not None:
       raise result.outch1
     if result.ouch2 is not None:
@@ -3266,15 +3647,16 @@
     self._oprot.trans.flush()
 
   def recv_createWriter(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = createWriter_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.outch1 is not None:
@@ -3283,7 +3665,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "createWriter failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "createWriter failed: unknown result")
 
   def update(self, writer, cells):
     """
@@ -3294,7 +3676,7 @@
     self.send_update(writer, cells)
 
   def send_update(self, writer, cells):
-    self._oprot.writeMessageBegin('update', TMessageType.CALL, self._seqid)
+    self._oprot.writeMessageBegin('update', TMessageType.ONEWAY, self._seqid)
     args = update_args()
     args.writer = writer
     args.cells = cells
@@ -3318,15 +3700,16 @@
     self._oprot.trans.flush()
 
   def recv_flush(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = flush_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -3350,15 +3733,16 @@
     self._oprot.trans.flush()
 
   def recv_closeWriter(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = closeWriter_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.ouch1 is not None:
       raise result.ouch1
     if result.ouch2 is not None:
@@ -3388,15 +3772,16 @@
     self._oprot.trans.flush()
 
   def recv_updateRowConditionally(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = updateRowConditionally_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -3405,7 +3790,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "updateRowConditionally failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "updateRowConditionally failed: unknown result")
 
   def createConditionalWriter(self, login, tableName, options):
     """
@@ -3428,15 +3813,16 @@
     self._oprot.trans.flush()
 
   def recv_createConditionalWriter(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = createConditionalWriter_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -3445,7 +3831,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "createConditionalWriter failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "createConditionalWriter failed: unknown result")
 
   def updateRowsConditionally(self, conditionalWriter, updates):
     """
@@ -3466,15 +3852,16 @@
     self._oprot.trans.flush()
 
   def recv_updateRowsConditionally(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = updateRowsConditionally_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
     if result.ouch1 is not None:
@@ -3483,7 +3870,7 @@
       raise result.ouch2
     if result.ouch3 is not None:
       raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "updateRowsConditionally failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "updateRowsConditionally failed: unknown result")
 
   def closeConditionalWriter(self, conditionalWriter):
     """
@@ -3502,15 +3889,16 @@
     self._oprot.trans.flush()
 
   def recv_closeConditionalWriter(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = closeConditionalWriter_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     return
 
   def getRowRange(self, row):
@@ -3530,18 +3918,19 @@
     self._oprot.trans.flush()
 
   def recv_getRowRange(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getRowRange_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getRowRange failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getRowRange failed: unknown result")
 
   def getFollowing(self, key, part):
     """
@@ -3562,18 +3951,781 @@
     self._oprot.trans.flush()
 
   def recv_getFollowing(self):
-    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
     if mtype == TMessageType.EXCEPTION:
       x = TApplicationException()
-      x.read(self._iprot)
-      self._iprot.readMessageEnd()
+      x.read(iprot)
+      iprot.readMessageEnd()
       raise x
     result = getFollowing_result()
-    result.read(self._iprot)
-    self._iprot.readMessageEnd()
+    result.read(iprot)
+    iprot.readMessageEnd()
     if result.success is not None:
       return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getFollowing failed: unknown result");
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getFollowing failed: unknown result")
+
+  def systemNamespace(self):
+    self.send_systemNamespace()
+    return self.recv_systemNamespace()
+
+  def send_systemNamespace(self):
+    self._oprot.writeMessageBegin('systemNamespace', TMessageType.CALL, self._seqid)
+    args = systemNamespace_args()
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_systemNamespace(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = systemNamespace_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "systemNamespace failed: unknown result")
+
+  def defaultNamespace(self):
+    self.send_defaultNamespace()
+    return self.recv_defaultNamespace()
+
+  def send_defaultNamespace(self):
+    self._oprot.writeMessageBegin('defaultNamespace', TMessageType.CALL, self._seqid)
+    args = defaultNamespace_args()
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_defaultNamespace(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = defaultNamespace_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "defaultNamespace failed: unknown result")
+
+  def listNamespaces(self, login):
+    """
+    Parameters:
+     - login
+    """
+    self.send_listNamespaces(login)
+    return self.recv_listNamespaces()
+
+  def send_listNamespaces(self, login):
+    self._oprot.writeMessageBegin('listNamespaces', TMessageType.CALL, self._seqid)
+    args = listNamespaces_args()
+    args.login = login
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_listNamespaces(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = listNamespaces_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "listNamespaces failed: unknown result")
+
+  def namespaceExists(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    self.send_namespaceExists(login, namespaceName)
+    return self.recv_namespaceExists()
+
+  def send_namespaceExists(self, login, namespaceName):
+    self._oprot.writeMessageBegin('namespaceExists', TMessageType.CALL, self._seqid)
+    args = namespaceExists_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_namespaceExists(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = namespaceExists_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "namespaceExists failed: unknown result")
+
+  def createNamespace(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    self.send_createNamespace(login, namespaceName)
+    self.recv_createNamespace()
+
+  def send_createNamespace(self, login, namespaceName):
+    self._oprot.writeMessageBegin('createNamespace', TMessageType.CALL, self._seqid)
+    args = createNamespace_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_createNamespace(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = createNamespace_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    return
+
+  def deleteNamespace(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    self.send_deleteNamespace(login, namespaceName)
+    self.recv_deleteNamespace()
+
+  def send_deleteNamespace(self, login, namespaceName):
+    self._oprot.writeMessageBegin('deleteNamespace', TMessageType.CALL, self._seqid)
+    args = deleteNamespace_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_deleteNamespace(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = deleteNamespace_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    if result.ouch4 is not None:
+      raise result.ouch4
+    return
+
+  def renameNamespace(self, login, oldNamespaceName, newNamespaceName):
+    """
+    Parameters:
+     - login
+     - oldNamespaceName
+     - newNamespaceName
+    """
+    self.send_renameNamespace(login, oldNamespaceName, newNamespaceName)
+    self.recv_renameNamespace()
+
+  def send_renameNamespace(self, login, oldNamespaceName, newNamespaceName):
+    self._oprot.writeMessageBegin('renameNamespace', TMessageType.CALL, self._seqid)
+    args = renameNamespace_args()
+    args.login = login
+    args.oldNamespaceName = oldNamespaceName
+    args.newNamespaceName = newNamespaceName
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_renameNamespace(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = renameNamespace_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    if result.ouch4 is not None:
+      raise result.ouch4
+    return
+
+  def setNamespaceProperty(self, login, namespaceName, property, value):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - property
+     - value
+    """
+    self.send_setNamespaceProperty(login, namespaceName, property, value)
+    self.recv_setNamespaceProperty()
+
+  def send_setNamespaceProperty(self, login, namespaceName, property, value):
+    self._oprot.writeMessageBegin('setNamespaceProperty', TMessageType.CALL, self._seqid)
+    args = setNamespaceProperty_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.property = property
+    args.value = value
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_setNamespaceProperty(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = setNamespaceProperty_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    return
+
+  def removeNamespaceProperty(self, login, namespaceName, property):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - property
+    """
+    self.send_removeNamespaceProperty(login, namespaceName, property)
+    self.recv_removeNamespaceProperty()
+
+  def send_removeNamespaceProperty(self, login, namespaceName, property):
+    self._oprot.writeMessageBegin('removeNamespaceProperty', TMessageType.CALL, self._seqid)
+    args = removeNamespaceProperty_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.property = property
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_removeNamespaceProperty(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = removeNamespaceProperty_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    return
+
+  def getNamespaceProperties(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    self.send_getNamespaceProperties(login, namespaceName)
+    return self.recv_getNamespaceProperties()
+
+  def send_getNamespaceProperties(self, login, namespaceName):
+    self._oprot.writeMessageBegin('getNamespaceProperties', TMessageType.CALL, self._seqid)
+    args = getNamespaceProperties_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_getNamespaceProperties(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = getNamespaceProperties_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getNamespaceProperties failed: unknown result")
+
+  def namespaceIdMap(self, login):
+    """
+    Parameters:
+     - login
+    """
+    self.send_namespaceIdMap(login)
+    return self.recv_namespaceIdMap()
+
+  def send_namespaceIdMap(self, login):
+    self._oprot.writeMessageBegin('namespaceIdMap', TMessageType.CALL, self._seqid)
+    args = namespaceIdMap_args()
+    args.login = login
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_namespaceIdMap(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = namespaceIdMap_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "namespaceIdMap failed: unknown result")
+
+  def attachNamespaceIterator(self, login, namespaceName, setting, scopes):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - setting
+     - scopes
+    """
+    self.send_attachNamespaceIterator(login, namespaceName, setting, scopes)
+    self.recv_attachNamespaceIterator()
+
+  def send_attachNamespaceIterator(self, login, namespaceName, setting, scopes):
+    self._oprot.writeMessageBegin('attachNamespaceIterator', TMessageType.CALL, self._seqid)
+    args = attachNamespaceIterator_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.setting = setting
+    args.scopes = scopes
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_attachNamespaceIterator(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = attachNamespaceIterator_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    return
+
+  def removeNamespaceIterator(self, login, namespaceName, name, scopes):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - name
+     - scopes
+    """
+    self.send_removeNamespaceIterator(login, namespaceName, name, scopes)
+    self.recv_removeNamespaceIterator()
+
+  def send_removeNamespaceIterator(self, login, namespaceName, name, scopes):
+    self._oprot.writeMessageBegin('removeNamespaceIterator', TMessageType.CALL, self._seqid)
+    args = removeNamespaceIterator_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.name = name
+    args.scopes = scopes
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_removeNamespaceIterator(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = removeNamespaceIterator_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    return
+
+  def getNamespaceIteratorSetting(self, login, namespaceName, name, scope):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - name
+     - scope
+    """
+    self.send_getNamespaceIteratorSetting(login, namespaceName, name, scope)
+    return self.recv_getNamespaceIteratorSetting()
+
+  def send_getNamespaceIteratorSetting(self, login, namespaceName, name, scope):
+    self._oprot.writeMessageBegin('getNamespaceIteratorSetting', TMessageType.CALL, self._seqid)
+    args = getNamespaceIteratorSetting_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.name = name
+    args.scope = scope
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_getNamespaceIteratorSetting(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = getNamespaceIteratorSetting_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "getNamespaceIteratorSetting failed: unknown result")
+
+  def listNamespaceIterators(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    self.send_listNamespaceIterators(login, namespaceName)
+    return self.recv_listNamespaceIterators()
+
+  def send_listNamespaceIterators(self, login, namespaceName):
+    self._oprot.writeMessageBegin('listNamespaceIterators', TMessageType.CALL, self._seqid)
+    args = listNamespaceIterators_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_listNamespaceIterators(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = listNamespaceIterators_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "listNamespaceIterators failed: unknown result")
+
+  def checkNamespaceIteratorConflicts(self, login, namespaceName, setting, scopes):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - setting
+     - scopes
+    """
+    self.send_checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes)
+    self.recv_checkNamespaceIteratorConflicts()
+
+  def send_checkNamespaceIteratorConflicts(self, login, namespaceName, setting, scopes):
+    self._oprot.writeMessageBegin('checkNamespaceIteratorConflicts', TMessageType.CALL, self._seqid)
+    args = checkNamespaceIteratorConflicts_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.setting = setting
+    args.scopes = scopes
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_checkNamespaceIteratorConflicts(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = checkNamespaceIteratorConflicts_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    return
+
+  def addNamespaceConstraint(self, login, namespaceName, constraintClassName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - constraintClassName
+    """
+    self.send_addNamespaceConstraint(login, namespaceName, constraintClassName)
+    return self.recv_addNamespaceConstraint()
+
+  def send_addNamespaceConstraint(self, login, namespaceName, constraintClassName):
+    self._oprot.writeMessageBegin('addNamespaceConstraint', TMessageType.CALL, self._seqid)
+    args = addNamespaceConstraint_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.constraintClassName = constraintClassName
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_addNamespaceConstraint(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = addNamespaceConstraint_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "addNamespaceConstraint failed: unknown result")
+
+  def removeNamespaceConstraint(self, login, namespaceName, id):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - id
+    """
+    self.send_removeNamespaceConstraint(login, namespaceName, id)
+    self.recv_removeNamespaceConstraint()
+
+  def send_removeNamespaceConstraint(self, login, namespaceName, id):
+    self._oprot.writeMessageBegin('removeNamespaceConstraint', TMessageType.CALL, self._seqid)
+    args = removeNamespaceConstraint_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.id = id
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_removeNamespaceConstraint(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = removeNamespaceConstraint_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    return
+
+  def listNamespaceConstraints(self, login, namespaceName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+    """
+    self.send_listNamespaceConstraints(login, namespaceName)
+    return self.recv_listNamespaceConstraints()
+
+  def send_listNamespaceConstraints(self, login, namespaceName):
+    self._oprot.writeMessageBegin('listNamespaceConstraints', TMessageType.CALL, self._seqid)
+    args = listNamespaceConstraints_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_listNamespaceConstraints(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = listNamespaceConstraints_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "listNamespaceConstraints failed: unknown result")
+
+  def testNamespaceClassLoad(self, login, namespaceName, className, asTypeName):
+    """
+    Parameters:
+     - login
+     - namespaceName
+     - className
+     - asTypeName
+    """
+    self.send_testNamespaceClassLoad(login, namespaceName, className, asTypeName)
+    return self.recv_testNamespaceClassLoad()
+
+  def send_testNamespaceClassLoad(self, login, namespaceName, className, asTypeName):
+    self._oprot.writeMessageBegin('testNamespaceClassLoad', TMessageType.CALL, self._seqid)
+    args = testNamespaceClassLoad_args()
+    args.login = login
+    args.namespaceName = namespaceName
+    args.className = className
+    args.asTypeName = asTypeName
+    args.write(self._oprot)
+    self._oprot.writeMessageEnd()
+    self._oprot.trans.flush()
+
+  def recv_testNamespaceClassLoad(self):
+    iprot = self._iprot
+    (fname, mtype, rseqid) = iprot.readMessageBegin()
+    if mtype == TMessageType.EXCEPTION:
+      x = TApplicationException()
+      x.read(iprot)
+      iprot.readMessageEnd()
+      raise x
+    result = testNamespaceClassLoad_result()
+    result.read(iprot)
+    iprot.readMessageEnd()
+    if result.success is not None:
+      return result.success
+    if result.ouch1 is not None:
+      raise result.ouch1
+    if result.ouch2 is not None:
+      raise result.ouch2
+    if result.ouch3 is not None:
+      raise result.ouch3
+    raise TApplicationException(TApplicationException.MISSING_RESULT, "testNamespaceClassLoad failed: unknown result")
 
 
 class Processor(Iface, TProcessor):
@@ -3640,6 +4792,9 @@
     self._processMap["listLocalUsers"] = Processor.process_listLocalUsers
     self._processMap["revokeSystemPermission"] = Processor.process_revokeSystemPermission
     self._processMap["revokeTablePermission"] = Processor.process_revokeTablePermission
+    self._processMap["grantNamespacePermission"] = Processor.process_grantNamespacePermission
+    self._processMap["hasNamespacePermission"] = Processor.process_hasNamespacePermission
+    self._processMap["revokeNamespacePermission"] = Processor.process_revokeNamespacePermission
     self._processMap["createBatchScanner"] = Processor.process_createBatchScanner
     self._processMap["createScanner"] = Processor.process_createScanner
     self._processMap["hasNext"] = Processor.process_hasNext
@@ -3657,6 +4812,26 @@
     self._processMap["closeConditionalWriter"] = Processor.process_closeConditionalWriter
     self._processMap["getRowRange"] = Processor.process_getRowRange
     self._processMap["getFollowing"] = Processor.process_getFollowing
+    self._processMap["systemNamespace"] = Processor.process_systemNamespace
+    self._processMap["defaultNamespace"] = Processor.process_defaultNamespace
+    self._processMap["listNamespaces"] = Processor.process_listNamespaces
+    self._processMap["namespaceExists"] = Processor.process_namespaceExists
+    self._processMap["createNamespace"] = Processor.process_createNamespace
+    self._processMap["deleteNamespace"] = Processor.process_deleteNamespace
+    self._processMap["renameNamespace"] = Processor.process_renameNamespace
+    self._processMap["setNamespaceProperty"] = Processor.process_setNamespaceProperty
+    self._processMap["removeNamespaceProperty"] = Processor.process_removeNamespaceProperty
+    self._processMap["getNamespaceProperties"] = Processor.process_getNamespaceProperties
+    self._processMap["namespaceIdMap"] = Processor.process_namespaceIdMap
+    self._processMap["attachNamespaceIterator"] = Processor.process_attachNamespaceIterator
+    self._processMap["removeNamespaceIterator"] = Processor.process_removeNamespaceIterator
+    self._processMap["getNamespaceIteratorSetting"] = Processor.process_getNamespaceIteratorSetting
+    self._processMap["listNamespaceIterators"] = Processor.process_listNamespaceIterators
+    self._processMap["checkNamespaceIteratorConflicts"] = Processor.process_checkNamespaceIteratorConflicts
+    self._processMap["addNamespaceConstraint"] = Processor.process_addNamespaceConstraint
+    self._processMap["removeNamespaceConstraint"] = Processor.process_removeNamespaceConstraint
+    self._processMap["listNamespaceConstraints"] = Processor.process_listNamespaceConstraints
+    self._processMap["testNamespaceClassLoad"] = Processor.process_testNamespaceClassLoad
 
   def process(self, iprot, oprot):
     (name, type, seqid) = iprot.readMessageBegin()
@@ -3680,9 +4855,17 @@
     result = login_result()
     try:
       result.success = self._handler.login(args.principal, args.loginProperties)
-    except AccumuloSecurityException, ouch2:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("login", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("login", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3694,13 +4877,23 @@
     result = addConstraint_result()
     try:
       result.success = self._handler.addConstraint(args.login, args.tableName, args.constraintClassName)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("addConstraint", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("addConstraint", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3712,13 +4905,23 @@
     result = addSplits_result()
     try:
       self._handler.addSplits(args.login, args.tableName, args.splits)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("addSplits", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("addSplits", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3730,13 +4933,23 @@
     result = attachIterator_result()
     try:
       self._handler.attachIterator(args.login, args.tableName, args.setting, args.scopes)
-    except AccumuloSecurityException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloSecurityException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloException, ouch2:
+    except AccumuloException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("attachIterator", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("attachIterator", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3748,13 +4961,23 @@
     result = checkIteratorConflicts_result()
     try:
       self._handler.checkIteratorConflicts(args.login, args.tableName, args.setting, args.scopes)
-    except AccumuloSecurityException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloSecurityException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloException, ouch2:
+    except AccumuloException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("checkIteratorConflicts", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("checkIteratorConflicts", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3766,9 +4989,17 @@
     result = clearLocatorCache_result()
     try:
       self._handler.clearLocatorCache(args.login, args.tableName)
-    except TableNotFoundException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except TableNotFoundException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    oprot.writeMessageBegin("clearLocatorCache", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("clearLocatorCache", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3780,15 +5011,26 @@
     result = cloneTable_result()
     try:
       self._handler.cloneTable(args.login, args.tableName, args.newTableName, args.flush, args.propertiesToSet, args.propertiesToExclude)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    except TableExistsException, ouch4:
+    except TableExistsException as ouch4:
+      msg_type = TMessageType.REPLY
       result.ouch4 = ouch4
-    oprot.writeMessageBegin("cloneTable", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("cloneTable", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3800,13 +5042,23 @@
     result = compactTable_result()
     try:
       self._handler.compactTable(args.login, args.tableName, args.startRow, args.endRow, args.iterators, args.flush, args.wait, args.compactionStrategy)
-    except AccumuloSecurityException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloSecurityException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except TableNotFoundException, ouch2:
+    except TableNotFoundException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except AccumuloException, ouch3:
+    except AccumuloException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("compactTable", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("compactTable", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3818,13 +5070,23 @@
     result = cancelCompaction_result()
     try:
       self._handler.cancelCompaction(args.login, args.tableName)
-    except AccumuloSecurityException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloSecurityException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except TableNotFoundException, ouch2:
+    except TableNotFoundException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except AccumuloException, ouch3:
+    except AccumuloException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("cancelCompaction", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("cancelCompaction", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3836,13 +5098,23 @@
     result = createTable_result()
     try:
       self._handler.createTable(args.login, args.tableName, args.versioningIter, args.type)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableExistsException, ouch3:
+    except TableExistsException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("createTable", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("createTable", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3854,13 +5126,23 @@
     result = deleteTable_result()
     try:
       self._handler.deleteTable(args.login, args.tableName)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("deleteTable", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("deleteTable", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3872,13 +5154,23 @@
     result = deleteRows_result()
     try:
       self._handler.deleteRows(args.login, args.tableName, args.startRow, args.endRow)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("deleteRows", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("deleteRows", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3890,13 +5182,23 @@
     result = exportTable_result()
     try:
       self._handler.exportTable(args.login, args.tableName, args.exportDir)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("exportTable", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("exportTable", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3908,13 +5210,23 @@
     result = flushTable_result()
     try:
       self._handler.flushTable(args.login, args.tableName, args.startRow, args.endRow, args.wait)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("flushTable", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("flushTable", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3926,13 +5238,23 @@
     result = getDiskUsage_result()
     try:
       result.success = self._handler.getDiskUsage(args.login, args.tables)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("getDiskUsage", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getDiskUsage", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3944,13 +5266,23 @@
     result = getLocalityGroups_result()
     try:
       result.success = self._handler.getLocalityGroups(args.login, args.tableName)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("getLocalityGroups", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getLocalityGroups", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3962,13 +5294,23 @@
     result = getIteratorSetting_result()
     try:
       result.success = self._handler.getIteratorSetting(args.login, args.tableName, args.iteratorName, args.scope)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("getIteratorSetting", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getIteratorSetting", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3980,13 +5322,23 @@
     result = getMaxRow_result()
     try:
       result.success = self._handler.getMaxRow(args.login, args.tableName, args.auths, args.startRow, args.startInclusive, args.endRow, args.endInclusive)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("getMaxRow", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getMaxRow", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -3998,13 +5350,23 @@
     result = getTableProperties_result()
     try:
       result.success = self._handler.getTableProperties(args.login, args.tableName)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("getTableProperties", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getTableProperties", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4016,13 +5378,23 @@
     result = importDirectory_result()
     try:
       self._handler.importDirectory(args.login, args.tableName, args.importDir, args.failureDir, args.setTime)
-    except TableNotFoundException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except TableNotFoundException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloException, ouch3:
+    except AccumuloException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    except AccumuloSecurityException, ouch4:
+    except AccumuloSecurityException as ouch4:
+      msg_type = TMessageType.REPLY
       result.ouch4 = ouch4
-    oprot.writeMessageBegin("importDirectory", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("importDirectory", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4034,13 +5406,23 @@
     result = importTable_result()
     try:
       self._handler.importTable(args.login, args.tableName, args.importDir)
-    except TableExistsException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except TableExistsException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloException, ouch2:
+    except AccumuloException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except AccumuloSecurityException, ouch3:
+    except AccumuloSecurityException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("importTable", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("importTable", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4052,13 +5434,23 @@
     result = listSplits_result()
     try:
       result.success = self._handler.listSplits(args.login, args.tableName, args.maxSplits)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("listSplits", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("listSplits", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4068,8 +5460,16 @@
     args.read(iprot)
     iprot.readMessageEnd()
     result = listTables_result()
-    result.success = self._handler.listTables(args.login)
-    oprot.writeMessageBegin("listTables", TMessageType.REPLY, seqid)
+    try:
+      result.success = self._handler.listTables(args.login)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("listTables", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4081,13 +5481,23 @@
     result = listIterators_result()
     try:
       result.success = self._handler.listIterators(args.login, args.tableName)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("listIterators", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("listIterators", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4099,13 +5509,23 @@
     result = listConstraints_result()
     try:
       result.success = self._handler.listConstraints(args.login, args.tableName)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("listConstraints", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("listConstraints", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4117,13 +5537,23 @@
     result = mergeTablets_result()
     try:
       self._handler.mergeTablets(args.login, args.tableName, args.startRow, args.endRow)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("mergeTablets", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("mergeTablets", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4135,13 +5565,23 @@
     result = offlineTable_result()
     try:
       self._handler.offlineTable(args.login, args.tableName, args.wait)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("offlineTable", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("offlineTable", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4153,13 +5593,23 @@
     result = onlineTable_result()
     try:
       self._handler.onlineTable(args.login, args.tableName, args.wait)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("onlineTable", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("onlineTable", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4171,13 +5621,23 @@
     result = removeConstraint_result()
     try:
       self._handler.removeConstraint(args.login, args.tableName, args.constraint)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("removeConstraint", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("removeConstraint", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4189,13 +5649,23 @@
     result = removeIterator_result()
     try:
       self._handler.removeIterator(args.login, args.tableName, args.iterName, args.scopes)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("removeIterator", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("removeIterator", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4207,13 +5677,23 @@
     result = removeTableProperty_result()
     try:
       self._handler.removeTableProperty(args.login, args.tableName, args.property)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("removeTableProperty", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("removeTableProperty", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4225,15 +5705,26 @@
     result = renameTable_result()
     try:
       self._handler.renameTable(args.login, args.oldTableName, args.newTableName)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    except TableExistsException, ouch4:
+    except TableExistsException as ouch4:
+      msg_type = TMessageType.REPLY
       result.ouch4 = ouch4
-    oprot.writeMessageBegin("renameTable", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("renameTable", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4245,13 +5736,23 @@
     result = setLocalityGroups_result()
     try:
       self._handler.setLocalityGroups(args.login, args.tableName, args.groups)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("setLocalityGroups", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("setLocalityGroups", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4263,13 +5764,23 @@
     result = setTableProperty_result()
     try:
       self._handler.setTableProperty(args.login, args.tableName, args.property, args.value)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("setTableProperty", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("setTableProperty", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4281,13 +5792,23 @@
     result = splitRangeByTablets_result()
     try:
       result.success = self._handler.splitRangeByTablets(args.login, args.tableName, args.range, args.maxSplits)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("splitRangeByTablets", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("splitRangeByTablets", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4297,8 +5818,16 @@
     args.read(iprot)
     iprot.readMessageEnd()
     result = tableExists_result()
-    result.success = self._handler.tableExists(args.login, args.tableName)
-    oprot.writeMessageBegin("tableExists", TMessageType.REPLY, seqid)
+    try:
+      result.success = self._handler.tableExists(args.login, args.tableName)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("tableExists", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4308,8 +5837,16 @@
     args.read(iprot)
     iprot.readMessageEnd()
     result = tableIdMap_result()
-    result.success = self._handler.tableIdMap(args.login)
-    oprot.writeMessageBegin("tableIdMap", TMessageType.REPLY, seqid)
+    try:
+      result.success = self._handler.tableIdMap(args.login)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("tableIdMap", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4321,13 +5858,23 @@
     result = testTableClassLoad_result()
     try:
       result.success = self._handler.testTableClassLoad(args.login, args.tableName, args.className, args.asTypeName)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("testTableClassLoad", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("testTableClassLoad", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4339,11 +5886,20 @@
     result = pingTabletServer_result()
     try:
       self._handler.pingTabletServer(args.login, args.tserver)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("pingTabletServer", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("pingTabletServer", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4355,11 +5911,20 @@
     result = getActiveScans_result()
     try:
       result.success = self._handler.getActiveScans(args.login, args.tserver)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("getActiveScans", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getActiveScans", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4371,11 +5936,20 @@
     result = getActiveCompactions_result()
     try:
       result.success = self._handler.getActiveCompactions(args.login, args.tserver)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("getActiveCompactions", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getActiveCompactions", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4387,11 +5961,20 @@
     result = getSiteConfiguration_result()
     try:
       result.success = self._handler.getSiteConfiguration(args.login)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("getSiteConfiguration", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getSiteConfiguration", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4403,11 +5986,20 @@
     result = getSystemConfiguration_result()
     try:
       result.success = self._handler.getSystemConfiguration(args.login)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("getSystemConfiguration", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getSystemConfiguration", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4417,8 +6009,16 @@
     args.read(iprot)
     iprot.readMessageEnd()
     result = getTabletServers_result()
-    result.success = self._handler.getTabletServers(args.login)
-    oprot.writeMessageBegin("getTabletServers", TMessageType.REPLY, seqid)
+    try:
+      result.success = self._handler.getTabletServers(args.login)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getTabletServers", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4430,11 +6030,20 @@
     result = removeProperty_result()
     try:
       self._handler.removeProperty(args.login, args.property)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("removeProperty", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("removeProperty", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4446,11 +6055,20 @@
     result = setProperty_result()
     try:
       self._handler.setProperty(args.login, args.property, args.value)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("setProperty", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("setProperty", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4462,11 +6080,20 @@
     result = testClassLoad_result()
     try:
       result.success = self._handler.testClassLoad(args.login, args.className, args.asTypeName)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("testClassLoad", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("testClassLoad", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4478,11 +6105,20 @@
     result = authenticateUser_result()
     try:
       result.success = self._handler.authenticateUser(args.login, args.user, args.properties)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("authenticateUser", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("authenticateUser", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4494,11 +6130,20 @@
     result = changeUserAuthorizations_result()
     try:
       self._handler.changeUserAuthorizations(args.login, args.user, args.authorizations)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("changeUserAuthorizations", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("changeUserAuthorizations", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4510,11 +6155,20 @@
     result = changeLocalUserPassword_result()
     try:
       self._handler.changeLocalUserPassword(args.login, args.user, args.password)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("changeLocalUserPassword", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("changeLocalUserPassword", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4526,11 +6180,20 @@
     result = createLocalUser_result()
     try:
       self._handler.createLocalUser(args.login, args.user, args.password)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("createLocalUser", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("createLocalUser", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4542,11 +6205,20 @@
     result = dropLocalUser_result()
     try:
       self._handler.dropLocalUser(args.login, args.user)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("dropLocalUser", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("dropLocalUser", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4558,11 +6230,20 @@
     result = getUserAuthorizations_result()
     try:
       result.success = self._handler.getUserAuthorizations(args.login, args.user)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("getUserAuthorizations", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getUserAuthorizations", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4574,11 +6255,20 @@
     result = grantSystemPermission_result()
     try:
       self._handler.grantSystemPermission(args.login, args.user, args.perm)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("grantSystemPermission", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("grantSystemPermission", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4590,13 +6280,23 @@
     result = grantTablePermission_result()
     try:
       self._handler.grantTablePermission(args.login, args.user, args.table, args.perm)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("grantTablePermission", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("grantTablePermission", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4608,11 +6308,20 @@
     result = hasSystemPermission_result()
     try:
       result.success = self._handler.hasSystemPermission(args.login, args.user, args.perm)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("hasSystemPermission", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("hasSystemPermission", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4624,13 +6333,23 @@
     result = hasTablePermission_result()
     try:
       result.success = self._handler.hasTablePermission(args.login, args.user, args.table, args.perm)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("hasTablePermission", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("hasTablePermission", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4642,13 +6361,23 @@
     result = listLocalUsers_result()
     try:
       result.success = self._handler.listLocalUsers(args.login)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("listLocalUsers", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("listLocalUsers", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4660,11 +6389,20 @@
     result = revokeSystemPermission_result()
     try:
       self._handler.revokeSystemPermission(args.login, args.user, args.perm)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("revokeSystemPermission", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("revokeSystemPermission", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4676,13 +6414,98 @@
     result = revokeTablePermission_result()
     try:
       self._handler.revokeTablePermission(args.login, args.user, args.table, args.perm)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("revokeTablePermission", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("revokeTablePermission", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_grantNamespacePermission(self, seqid, iprot, oprot):
+    args = grantNamespacePermission_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = grantNamespacePermission_result()
+    try:
+      self._handler.grantNamespacePermission(args.login, args.user, args.namespaceName, args.perm)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("grantNamespacePermission", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_hasNamespacePermission(self, seqid, iprot, oprot):
+    args = hasNamespacePermission_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = hasNamespacePermission_result()
+    try:
+      result.success = self._handler.hasNamespacePermission(args.login, args.user, args.namespaceName, args.perm)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("hasNamespacePermission", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_revokeNamespacePermission(self, seqid, iprot, oprot):
+    args = revokeNamespacePermission_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = revokeNamespacePermission_result()
+    try:
+      self._handler.revokeNamespacePermission(args.login, args.user, args.namespaceName, args.perm)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("revokeNamespacePermission", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4694,13 +6517,23 @@
     result = createBatchScanner_result()
     try:
       result.success = self._handler.createBatchScanner(args.login, args.tableName, args.options)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("createBatchScanner", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("createBatchScanner", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4712,13 +6545,23 @@
     result = createScanner_result()
     try:
       result.success = self._handler.createScanner(args.login, args.tableName, args.options)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("createScanner", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("createScanner", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4730,9 +6573,17 @@
     result = hasNext_result()
     try:
       result.success = self._handler.hasNext(args.scanner)
-    except UnknownScanner, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except UnknownScanner as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    oprot.writeMessageBegin("hasNext", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("hasNext", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4744,13 +6595,23 @@
     result = nextEntry_result()
     try:
       result.success = self._handler.nextEntry(args.scanner)
-    except NoMoreEntriesException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except NoMoreEntriesException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except UnknownScanner, ouch2:
+    except UnknownScanner as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except AccumuloSecurityException, ouch3:
+    except AccumuloSecurityException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("nextEntry", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("nextEntry", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4762,13 +6623,23 @@
     result = nextK_result()
     try:
       result.success = self._handler.nextK(args.scanner, args.k)
-    except NoMoreEntriesException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except NoMoreEntriesException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except UnknownScanner, ouch2:
+    except UnknownScanner as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except AccumuloSecurityException, ouch3:
+    except AccumuloSecurityException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("nextK", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("nextK", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4780,9 +6651,17 @@
     result = closeScanner_result()
     try:
       self._handler.closeScanner(args.scanner)
-    except UnknownScanner, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except UnknownScanner as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    oprot.writeMessageBegin("closeScanner", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("closeScanner", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4794,15 +6673,26 @@
     result = updateAndFlush_result()
     try:
       self._handler.updateAndFlush(args.login, args.tableName, args.cells)
-    except AccumuloException, outch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as outch1:
+      msg_type = TMessageType.REPLY
       result.outch1 = outch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    except MutationsRejectedException, ouch4:
+    except MutationsRejectedException as ouch4:
+      msg_type = TMessageType.REPLY
       result.ouch4 = ouch4
-    oprot.writeMessageBegin("updateAndFlush", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("updateAndFlush", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4814,13 +6704,23 @@
     result = createWriter_result()
     try:
       result.success = self._handler.createWriter(args.login, args.tableName, args.opts)
-    except AccumuloException, outch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as outch1:
+      msg_type = TMessageType.REPLY
       result.outch1 = outch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("createWriter", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("createWriter", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4829,8 +6729,13 @@
     args = update_args()
     args.read(iprot)
     iprot.readMessageEnd()
-    self._handler.update(args.writer, args.cells)
-    return
+    try:
+      self._handler.update(args.writer, args.cells)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except:
+      pass
 
   def process_flush(self, seqid, iprot, oprot):
     args = flush_args()
@@ -4839,11 +6744,20 @@
     result = flush_result()
     try:
       self._handler.flush(args.writer)
-    except UnknownWriter, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except UnknownWriter as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except MutationsRejectedException, ouch2:
+    except MutationsRejectedException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("flush", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("flush", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4855,11 +6769,20 @@
     result = closeWriter_result()
     try:
       self._handler.closeWriter(args.writer)
-    except UnknownWriter, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except UnknownWriter as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except MutationsRejectedException, ouch2:
+    except MutationsRejectedException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    oprot.writeMessageBegin("closeWriter", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("closeWriter", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4871,13 +6794,23 @@
     result = updateRowConditionally_result()
     try:
       result.success = self._handler.updateRowConditionally(args.login, args.tableName, args.row, args.updates)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("updateRowConditionally", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("updateRowConditionally", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4889,13 +6822,23 @@
     result = createConditionalWriter_result()
     try:
       result.success = self._handler.createConditionalWriter(args.login, args.tableName, args.options)
-    except AccumuloException, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloSecurityException, ouch2:
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except TableNotFoundException, ouch3:
+    except TableNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("createConditionalWriter", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("createConditionalWriter", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4907,13 +6850,23 @@
     result = updateRowsConditionally_result()
     try:
       result.success = self._handler.updateRowsConditionally(args.conditionalWriter, args.updates)
-    except UnknownWriter, ouch1:
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except UnknownWriter as ouch1:
+      msg_type = TMessageType.REPLY
       result.ouch1 = ouch1
-    except AccumuloException, ouch2:
+    except AccumuloException as ouch2:
+      msg_type = TMessageType.REPLY
       result.ouch2 = ouch2
-    except AccumuloSecurityException, ouch3:
+    except AccumuloSecurityException as ouch3:
+      msg_type = TMessageType.REPLY
       result.ouch3 = ouch3
-    oprot.writeMessageBegin("updateRowsConditionally", TMessageType.REPLY, seqid)
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("updateRowsConditionally", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4923,8 +6876,16 @@
     args.read(iprot)
     iprot.readMessageEnd()
     result = closeConditionalWriter_result()
-    self._handler.closeConditionalWriter(args.conditionalWriter)
-    oprot.writeMessageBegin("closeConditionalWriter", TMessageType.REPLY, seqid)
+    try:
+      self._handler.closeConditionalWriter(args.conditionalWriter)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("closeConditionalWriter", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4934,8 +6895,16 @@
     args.read(iprot)
     iprot.readMessageEnd()
     result = getRowRange_result()
-    result.success = self._handler.getRowRange(args.row)
-    oprot.writeMessageBegin("getRowRange", TMessageType.REPLY, seqid)
+    try:
+      result.success = self._handler.getRowRange(args.row)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getRowRange", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4945,8 +6914,555 @@
     args.read(iprot)
     iprot.readMessageEnd()
     result = getFollowing_result()
-    result.success = self._handler.getFollowing(args.key, args.part)
-    oprot.writeMessageBegin("getFollowing", TMessageType.REPLY, seqid)
+    try:
+      result.success = self._handler.getFollowing(args.key, args.part)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getFollowing", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_systemNamespace(self, seqid, iprot, oprot):
+    args = systemNamespace_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = systemNamespace_result()
+    try:
+      result.success = self._handler.systemNamespace()
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("systemNamespace", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_defaultNamespace(self, seqid, iprot, oprot):
+    args = defaultNamespace_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = defaultNamespace_result()
+    try:
+      result.success = self._handler.defaultNamespace()
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("defaultNamespace", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_listNamespaces(self, seqid, iprot, oprot):
+    args = listNamespaces_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = listNamespaces_result()
+    try:
+      result.success = self._handler.listNamespaces(args.login)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("listNamespaces", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_namespaceExists(self, seqid, iprot, oprot):
+    args = namespaceExists_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = namespaceExists_result()
+    try:
+      result.success = self._handler.namespaceExists(args.login, args.namespaceName)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("namespaceExists", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_createNamespace(self, seqid, iprot, oprot):
+    args = createNamespace_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = createNamespace_result()
+    try:
+      self._handler.createNamespace(args.login, args.namespaceName)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceExistsException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("createNamespace", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_deleteNamespace(self, seqid, iprot, oprot):
+    args = deleteNamespace_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = deleteNamespace_result()
+    try:
+      self._handler.deleteNamespace(args.login, args.namespaceName)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except NamespaceNotEmptyException as ouch4:
+      msg_type = TMessageType.REPLY
+      result.ouch4 = ouch4
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("deleteNamespace", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_renameNamespace(self, seqid, iprot, oprot):
+    args = renameNamespace_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = renameNamespace_result()
+    try:
+      self._handler.renameNamespace(args.login, args.oldNamespaceName, args.newNamespaceName)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except NamespaceExistsException as ouch4:
+      msg_type = TMessageType.REPLY
+      result.ouch4 = ouch4
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("renameNamespace", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_setNamespaceProperty(self, seqid, iprot, oprot):
+    args = setNamespaceProperty_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = setNamespaceProperty_result()
+    try:
+      self._handler.setNamespaceProperty(args.login, args.namespaceName, args.property, args.value)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("setNamespaceProperty", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_removeNamespaceProperty(self, seqid, iprot, oprot):
+    args = removeNamespaceProperty_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = removeNamespaceProperty_result()
+    try:
+      self._handler.removeNamespaceProperty(args.login, args.namespaceName, args.property)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("removeNamespaceProperty", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_getNamespaceProperties(self, seqid, iprot, oprot):
+    args = getNamespaceProperties_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = getNamespaceProperties_result()
+    try:
+      result.success = self._handler.getNamespaceProperties(args.login, args.namespaceName)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getNamespaceProperties", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_namespaceIdMap(self, seqid, iprot, oprot):
+    args = namespaceIdMap_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = namespaceIdMap_result()
+    try:
+      result.success = self._handler.namespaceIdMap(args.login)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("namespaceIdMap", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_attachNamespaceIterator(self, seqid, iprot, oprot):
+    args = attachNamespaceIterator_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = attachNamespaceIterator_result()
+    try:
+      self._handler.attachNamespaceIterator(args.login, args.namespaceName, args.setting, args.scopes)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("attachNamespaceIterator", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_removeNamespaceIterator(self, seqid, iprot, oprot):
+    args = removeNamespaceIterator_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = removeNamespaceIterator_result()
+    try:
+      self._handler.removeNamespaceIterator(args.login, args.namespaceName, args.name, args.scopes)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("removeNamespaceIterator", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_getNamespaceIteratorSetting(self, seqid, iprot, oprot):
+    args = getNamespaceIteratorSetting_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = getNamespaceIteratorSetting_result()
+    try:
+      result.success = self._handler.getNamespaceIteratorSetting(args.login, args.namespaceName, args.name, args.scope)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("getNamespaceIteratorSetting", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_listNamespaceIterators(self, seqid, iprot, oprot):
+    args = listNamespaceIterators_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = listNamespaceIterators_result()
+    try:
+      result.success = self._handler.listNamespaceIterators(args.login, args.namespaceName)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("listNamespaceIterators", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_checkNamespaceIteratorConflicts(self, seqid, iprot, oprot):
+    args = checkNamespaceIteratorConflicts_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = checkNamespaceIteratorConflicts_result()
+    try:
+      self._handler.checkNamespaceIteratorConflicts(args.login, args.namespaceName, args.setting, args.scopes)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("checkNamespaceIteratorConflicts", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_addNamespaceConstraint(self, seqid, iprot, oprot):
+    args = addNamespaceConstraint_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = addNamespaceConstraint_result()
+    try:
+      result.success = self._handler.addNamespaceConstraint(args.login, args.namespaceName, args.constraintClassName)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("addNamespaceConstraint", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_removeNamespaceConstraint(self, seqid, iprot, oprot):
+    args = removeNamespaceConstraint_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = removeNamespaceConstraint_result()
+    try:
+      self._handler.removeNamespaceConstraint(args.login, args.namespaceName, args.id)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("removeNamespaceConstraint", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_listNamespaceConstraints(self, seqid, iprot, oprot):
+    args = listNamespaceConstraints_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = listNamespaceConstraints_result()
+    try:
+      result.success = self._handler.listNamespaceConstraints(args.login, args.namespaceName)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("listNamespaceConstraints", msg_type, seqid)
+    result.write(oprot)
+    oprot.writeMessageEnd()
+    oprot.trans.flush()
+
+  def process_testNamespaceClassLoad(self, seqid, iprot, oprot):
+    args = testNamespaceClassLoad_args()
+    args.read(iprot)
+    iprot.readMessageEnd()
+    result = testNamespaceClassLoad_result()
+    try:
+      result.success = self._handler.testNamespaceClassLoad(args.login, args.namespaceName, args.className, args.asTypeName)
+      msg_type = TMessageType.REPLY
+    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+      raise
+    except AccumuloException as ouch1:
+      msg_type = TMessageType.REPLY
+      result.ouch1 = ouch1
+    except AccumuloSecurityException as ouch2:
+      msg_type = TMessageType.REPLY
+      result.ouch2 = ouch2
+    except NamespaceNotFoundException as ouch3:
+      msg_type = TMessageType.REPLY
+      result.ouch3 = ouch3
+    except Exception as ex:
+      msg_type = TMessageType.EXCEPTION
+      logging.exception(ex)
+      result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
+    oprot.writeMessageBegin("testNamespaceClassLoad", msg_type, seqid)
     result.write(oprot)
     oprot.writeMessageEnd()
     oprot.trans.flush()
@@ -4982,7 +7498,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.principal = iprot.readString();
+          self.principal = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
@@ -4990,8 +7506,8 @@
           self.loginProperties = {}
           (_ktype145, _vtype146, _size144 ) = iprot.readMapBegin()
           for _i148 in xrange(_size144):
-            _key149 = iprot.readString();
-            _val150 = iprot.readString();
+            _key149 = iprot.readString()
+            _val150 = iprot.readString()
             self.loginProperties[_key149] = _val150
           iprot.readMapEnd()
         else:
@@ -5025,6 +7541,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.principal)
+    value = (value * 31) ^ hash(self.loginProperties)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5063,7 +7585,7 @@
         break
       if fid == 0:
         if ftype == TType.STRING:
-          self.success = iprot.readString();
+          self.success = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -5097,6 +7619,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5139,17 +7667,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.constraintClassName = iprot.readString();
+          self.constraintClassName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -5181,6 +7709,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.constraintClassName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5225,7 +7760,7 @@
         break
       if fid == 0:
         if ftype == TType.I32:
-          self.success = iprot.readI32();
+          self.success = iprot.readI32()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -5279,6 +7814,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5321,12 +7864,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -5334,7 +7877,7 @@
           self.splits = set()
           (_etype156, _size153) = iprot.readSetBegin()
           for _i157 in xrange(_size153):
-            _elem158 = iprot.readString();
+            _elem158 = iprot.readString()
             self.splits.add(_elem158)
           iprot.readSetEnd()
         else:
@@ -5371,6 +7914,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.splits)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5458,6 +8008,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5503,12 +8060,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -5522,7 +8079,7 @@
           self.scopes = set()
           (_etype163, _size160) = iprot.readSetBegin()
           for _i164 in xrange(_size160):
-            _elem165 = iprot.readI32();
+            _elem165 = iprot.readI32()
             self.scopes.add(_elem165)
           iprot.readSetEnd()
         else:
@@ -5563,6 +8120,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.setting)
+    value = (value * 31) ^ hash(self.scopes)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5650,6 +8215,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5695,12 +8267,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -5714,7 +8286,7 @@
           self.scopes = set()
           (_etype170, _size167) = iprot.readSetBegin()
           for _i171 in xrange(_size167):
-            _elem172 = iprot.readI32();
+            _elem172 = iprot.readI32()
             self.scopes.add(_elem172)
           iprot.readSetEnd()
         else:
@@ -5755,6 +8327,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.setting)
+    value = (value * 31) ^ hash(self.scopes)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5842,6 +8422,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5881,12 +8468,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -5914,6 +8501,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -5975,6 +8568,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -6026,22 +8624,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.newTableName = iprot.readString();
+          self.newTableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.BOOL:
-          self.flush = iprot.readBool();
+          self.flush = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 5:
@@ -6049,8 +8647,8 @@
           self.propertiesToSet = {}
           (_ktype175, _vtype176, _size174 ) = iprot.readMapBegin()
           for _i178 in xrange(_size174):
-            _key179 = iprot.readString();
-            _val180 = iprot.readString();
+            _key179 = iprot.readString()
+            _val180 = iprot.readString()
             self.propertiesToSet[_key179] = _val180
           iprot.readMapEnd()
         else:
@@ -6060,7 +8658,7 @@
           self.propertiesToExclude = set()
           (_etype184, _size181) = iprot.readSetBegin()
           for _i185 in xrange(_size181):
-            _elem186 = iprot.readString();
+            _elem186 = iprot.readString()
             self.propertiesToExclude.add(_elem186)
           iprot.readSetEnd()
         else:
@@ -6113,6 +8711,16 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.newTableName)
+    value = (value * 31) ^ hash(self.flush)
+    value = (value * 31) ^ hash(self.propertiesToSet)
+    value = (value * 31) ^ hash(self.propertiesToExclude)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -6213,6 +8821,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    value = (value * 31) ^ hash(self.ouch4)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -6270,22 +8886,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.startRow = iprot.readString();
+          self.startRow = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.STRING:
-          self.endRow = iprot.readString();
+          self.endRow = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 5:
@@ -6301,12 +8917,12 @@
           iprot.skip(ftype)
       elif fid == 6:
         if ftype == TType.BOOL:
-          self.flush = iprot.readBool();
+          self.flush = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 7:
         if ftype == TType.BOOL:
-          self.wait = iprot.readBool();
+          self.wait = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 8:
@@ -6367,6 +8983,18 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.startRow)
+    value = (value * 31) ^ hash(self.endRow)
+    value = (value * 31) ^ hash(self.iterators)
+    value = (value * 31) ^ hash(self.flush)
+    value = (value * 31) ^ hash(self.wait)
+    value = (value * 31) ^ hash(self.compactionStrategy)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -6454,6 +9082,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -6493,12 +9128,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -6526,6 +9161,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -6613,6 +9254,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -6658,22 +9306,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.BOOL:
-          self.versioningIter = iprot.readBool();
+          self.versioningIter = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.I32:
-          self.type = iprot.readI32();
+          self.type = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -6709,6 +9357,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.versioningIter)
+    value = (value * 31) ^ hash(self.type)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -6796,6 +9452,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -6835,12 +9498,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -6868,6 +9531,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -6955,6 +9624,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7000,22 +9676,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.startRow = iprot.readString();
+          self.startRow = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.STRING:
-          self.endRow = iprot.readString();
+          self.endRow = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -7051,6 +9727,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.startRow)
+    value = (value * 31) ^ hash(self.endRow)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7138,6 +9822,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7180,17 +9871,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.exportDir = iprot.readString();
+          self.exportDir = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -7222,6 +9913,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.exportDir)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7309,6 +10007,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7357,27 +10062,27 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.startRow = iprot.readString();
+          self.startRow = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.STRING:
-          self.endRow = iprot.readString();
+          self.endRow = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.BOOL:
-          self.wait = iprot.readBool();
+          self.wait = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -7417,6 +10122,15 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.startRow)
+    value = (value * 31) ^ hash(self.endRow)
+    value = (value * 31) ^ hash(self.wait)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7504,6 +10218,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7543,7 +10264,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
@@ -7551,7 +10272,7 @@
           self.tables = set()
           (_etype200, _size197) = iprot.readSetBegin()
           for _i201 in xrange(_size197):
-            _elem202 = iprot.readString();
+            _elem202 = iprot.readString()
             self.tables.add(_elem202)
           iprot.readSetEnd()
         else:
@@ -7584,6 +10305,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tables)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7691,6 +10418,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7730,12 +10465,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -7763,6 +10498,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7810,11 +10551,11 @@
           self.success = {}
           (_ktype212, _vtype213, _size211 ) = iprot.readMapBegin()
           for _i215 in xrange(_size211):
-            _key216 = iprot.readString();
+            _key216 = iprot.readString()
             _val217 = set()
             (_etype221, _size218) = iprot.readSetBegin()
             for _i222 in xrange(_size218):
-              _elem223 = iprot.readString();
+              _elem223 = iprot.readString()
               _val217.add(_elem223)
             iprot.readSetEnd()
             self.success[_key216] = _val217
@@ -7879,6 +10620,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -7924,22 +10673,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.iteratorName = iprot.readString();
+          self.iteratorName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.I32:
-          self.scope = iprot.readI32();
+          self.scope = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -7975,6 +10724,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.iteratorName)
+    value = (value * 31) ^ hash(self.scope)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8074,6 +10831,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8128,12 +10893,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -8141,29 +10906,29 @@
           self.auths = set()
           (_etype230, _size227) = iprot.readSetBegin()
           for _i231 in xrange(_size227):
-            _elem232 = iprot.readString();
+            _elem232 = iprot.readString()
             self.auths.add(_elem232)
           iprot.readSetEnd()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.STRING:
-          self.startRow = iprot.readString();
+          self.startRow = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.BOOL:
-          self.startInclusive = iprot.readBool();
+          self.startInclusive = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 6:
         if ftype == TType.STRING:
-          self.endRow = iprot.readString();
+          self.endRow = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 7:
         if ftype == TType.BOOL:
-          self.endInclusive = iprot.readBool();
+          self.endInclusive = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -8214,6 +10979,17 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.auths)
+    value = (value * 31) ^ hash(self.startRow)
+    value = (value * 31) ^ hash(self.startInclusive)
+    value = (value * 31) ^ hash(self.endRow)
+    value = (value * 31) ^ hash(self.endInclusive)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8258,7 +11034,7 @@
         break
       if fid == 0:
         if ftype == TType.STRING:
-          self.success = iprot.readString();
+          self.success = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -8312,6 +11088,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8351,12 +11135,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -8384,6 +11168,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8431,8 +11221,8 @@
           self.success = {}
           (_ktype235, _vtype236, _size234 ) = iprot.readMapBegin()
           for _i238 in xrange(_size234):
-            _key239 = iprot.readString();
-            _val240 = iprot.readString();
+            _key239 = iprot.readString()
+            _val240 = iprot.readString()
             self.success[_key239] = _val240
           iprot.readMapEnd()
         else:
@@ -8492,6 +11282,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8540,27 +11338,27 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.importDir = iprot.readString();
+          self.importDir = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.STRING:
-          self.failureDir = iprot.readString();
+          self.failureDir = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.BOOL:
-          self.setTime = iprot.readBool();
+          self.setTime = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -8600,6 +11398,15 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.importDir)
+    value = (value * 31) ^ hash(self.failureDir)
+    value = (value * 31) ^ hash(self.setTime)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8687,6 +11494,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch3)
+    value = (value * 31) ^ hash(self.ouch4)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8729,17 +11543,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.importDir = iprot.readString();
+          self.importDir = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -8771,6 +11585,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.importDir)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8858,6 +11679,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8900,17 +11728,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.I32:
-          self.maxSplits = iprot.readI32();
+          self.maxSplits = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -8942,6 +11770,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.maxSplits)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -8989,7 +11824,7 @@
           self.success = []
           (_etype246, _size243) = iprot.readListBegin()
           for _i247 in xrange(_size243):
-            _elem248 = iprot.readString();
+            _elem248 = iprot.readString()
             self.success.append(_elem248)
           iprot.readListEnd()
         else:
@@ -9048,6 +11883,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9084,7 +11927,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -9108,6 +11951,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9146,7 +11994,7 @@
           self.success = set()
           (_etype253, _size250) = iprot.readSetBegin()
           for _i254 in xrange(_size250):
-            _elem255 = iprot.readString();
+            _elem255 = iprot.readString()
             self.success.add(_elem255)
           iprot.readSetEnd()
         else:
@@ -9175,6 +12023,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9214,12 +12067,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -9247,6 +12100,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9294,11 +12153,11 @@
           self.success = {}
           (_ktype258, _vtype259, _size257 ) = iprot.readMapBegin()
           for _i261 in xrange(_size257):
-            _key262 = iprot.readString();
+            _key262 = iprot.readString()
             _val263 = set()
             (_etype267, _size264) = iprot.readSetBegin()
             for _i268 in xrange(_size264):
-              _elem269 = iprot.readI32();
+              _elem269 = iprot.readI32()
               _val263.add(_elem269)
             iprot.readSetEnd()
             self.success[_key262] = _val263
@@ -9363,6 +12222,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9402,12 +12269,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -9435,6 +12302,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9482,8 +12355,8 @@
           self.success = {}
           (_ktype274, _vtype275, _size273 ) = iprot.readMapBegin()
           for _i277 in xrange(_size273):
-            _key278 = iprot.readString();
-            _val279 = iprot.readI32();
+            _key278 = iprot.readString()
+            _val279 = iprot.readI32()
             self.success[_key278] = _val279
           iprot.readMapEnd()
         else:
@@ -9543,6 +12416,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9588,22 +12469,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.startRow = iprot.readString();
+          self.startRow = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.STRING:
-          self.endRow = iprot.readString();
+          self.endRow = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -9639,6 +12520,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.startRow)
+    value = (value * 31) ^ hash(self.endRow)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9726,6 +12615,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9768,17 +12664,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.BOOL:
-          self.wait = iprot.readBool();
+          self.wait = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -9810,6 +12706,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.wait)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9897,6 +12800,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -9939,17 +12849,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.BOOL:
-          self.wait = iprot.readBool();
+          self.wait = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -9981,6 +12891,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.wait)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10068,6 +12985,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10110,17 +13034,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.I32:
-          self.constraint = iprot.readI32();
+          self.constraint = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -10152,6 +13076,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.constraint)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10239,6 +13170,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10284,17 +13222,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.iterName = iprot.readString();
+          self.iterName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
@@ -10302,7 +13240,7 @@
           self.scopes = set()
           (_etype285, _size282) = iprot.readSetBegin()
           for _i286 in xrange(_size282):
-            _elem287 = iprot.readI32();
+            _elem287 = iprot.readI32()
             self.scopes.add(_elem287)
           iprot.readSetEnd()
         else:
@@ -10343,6 +13281,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.iterName)
+    value = (value * 31) ^ hash(self.scopes)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10430,6 +13376,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10472,17 +13425,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.property = iprot.readString();
+          self.property = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -10514,6 +13467,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.property)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10601,6 +13561,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10643,17 +13610,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.oldTableName = iprot.readString();
+          self.oldTableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.newTableName = iprot.readString();
+          self.newTableName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -10685,6 +13652,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.oldTableName)
+    value = (value * 31) ^ hash(self.newTableName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10785,6 +13759,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    value = (value * 31) ^ hash(self.ouch4)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10827,12 +13809,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -10840,11 +13822,11 @@
           self.groups = {}
           (_ktype290, _vtype291, _size289 ) = iprot.readMapBegin()
           for _i293 in xrange(_size289):
-            _key294 = iprot.readString();
+            _key294 = iprot.readString()
             _val295 = set()
             (_etype299, _size296) = iprot.readSetBegin()
             for _i300 in xrange(_size296):
-              _elem301 = iprot.readString();
+              _elem301 = iprot.readString()
               _val295.add(_elem301)
             iprot.readSetEnd()
             self.groups[_key294] = _val295
@@ -10887,6 +13869,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.groups)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -10974,6 +13963,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11019,22 +14015,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.property = iprot.readString();
+          self.property = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.STRING:
-          self.value = iprot.readString();
+          self.value = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -11070,6 +14066,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.property)
+    value = (value * 31) ^ hash(self.value)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11157,6 +14161,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11202,12 +14213,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -11218,7 +14229,7 @@
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.I32:
-          self.maxSplits = iprot.readI32();
+          self.maxSplits = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -11254,6 +14265,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.range)
+    value = (value * 31) ^ hash(self.maxSplits)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11361,6 +14380,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11400,12 +14427,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -11433,6 +14460,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11468,7 +14501,7 @@
         break
       if fid == 0:
         if ftype == TType.BOOL:
-          self.success = iprot.readBool();
+          self.success = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -11492,6 +14525,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11528,7 +14566,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -11552,6 +14590,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11590,8 +14633,8 @@
           self.success = {}
           (_ktype313, _vtype314, _size312 ) = iprot.readMapBegin()
           for _i316 in xrange(_size312):
-            _key317 = iprot.readString();
-            _val318 = iprot.readString();
+            _key317 = iprot.readString()
+            _val318 = iprot.readString()
             self.success[_key317] = _val318
           iprot.readMapEnd()
         else:
@@ -11621,6 +14664,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11666,22 +14714,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.className = iprot.readString();
+          self.className = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.STRING:
-          self.asTypeName = iprot.readString();
+          self.asTypeName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -11717,6 +14765,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.className)
+    value = (value * 31) ^ hash(self.asTypeName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11761,7 +14817,7 @@
         break
       if fid == 0:
         if ftype == TType.BOOL:
-          self.success = iprot.readBool();
+          self.success = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -11815,6 +14871,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11854,12 +14918,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tserver = iprot.readString();
+          self.tserver = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -11887,6 +14951,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tserver)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -11961,6 +15031,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12000,12 +15076,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tserver = iprot.readString();
+          self.tserver = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -12033,6 +15109,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tserver)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12127,6 +15209,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12166,12 +15255,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tserver = iprot.readString();
+          self.tserver = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -12199,6 +15288,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tserver)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12293,6 +15388,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12329,7 +15431,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -12353,6 +15455,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12397,8 +15504,8 @@
           self.success = {}
           (_ktype336, _vtype337, _size335 ) = iprot.readMapBegin()
           for _i339 in xrange(_size335):
-            _key340 = iprot.readString();
-            _val341 = iprot.readString();
+            _key340 = iprot.readString()
+            _val341 = iprot.readString()
             self.success[_key340] = _val341
           iprot.readMapEnd()
         else:
@@ -12448,6 +15555,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12484,7 +15598,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -12508,6 +15622,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12552,8 +15671,8 @@
           self.success = {}
           (_ktype345, _vtype346, _size344 ) = iprot.readMapBegin()
           for _i348 in xrange(_size344):
-            _key349 = iprot.readString();
-            _val350 = iprot.readString();
+            _key349 = iprot.readString()
+            _val350 = iprot.readString()
             self.success[_key349] = _val350
           iprot.readMapEnd()
         else:
@@ -12603,6 +15722,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12639,7 +15765,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -12663,6 +15789,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12701,7 +15832,7 @@
           self.success = []
           (_etype356, _size353) = iprot.readListBegin()
           for _i357 in xrange(_size353):
-            _elem358 = iprot.readString();
+            _elem358 = iprot.readString()
             self.success.append(_elem358)
           iprot.readListEnd()
         else:
@@ -12730,6 +15861,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12769,12 +15905,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.property = iprot.readString();
+          self.property = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -12802,6 +15938,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.property)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12876,6 +16018,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -12918,17 +16066,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.property = iprot.readString();
+          self.property = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.value = iprot.readString();
+          self.value = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -12960,6 +16108,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.property)
+    value = (value * 31) ^ hash(self.value)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13034,6 +16189,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13076,17 +16237,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.className = iprot.readString();
+          self.className = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.asTypeName = iprot.readString();
+          self.asTypeName = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -13118,6 +16279,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.className)
+    value = (value * 31) ^ hash(self.asTypeName)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13159,7 +16327,7 @@
         break
       if fid == 0:
         if ftype == TType.BOOL:
-          self.success = iprot.readBool();
+          self.success = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -13203,6 +16371,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13245,12 +16420,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -13258,8 +16433,8 @@
           self.properties = {}
           (_ktype361, _vtype362, _size360 ) = iprot.readMapBegin()
           for _i364 in xrange(_size360):
-            _key365 = iprot.readString();
-            _val366 = iprot.readString();
+            _key365 = iprot.readString()
+            _val366 = iprot.readString()
             self.properties[_key365] = _val366
           iprot.readMapEnd()
         else:
@@ -13297,6 +16472,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.properties)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13338,7 +16520,7 @@
         break
       if fid == 0:
         if ftype == TType.BOOL:
-          self.success = iprot.readBool();
+          self.success = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -13382,6 +16564,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13424,12 +16613,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -13437,7 +16626,7 @@
           self.authorizations = set()
           (_etype372, _size369) = iprot.readSetBegin()
           for _i373 in xrange(_size369):
-            _elem374 = iprot.readString();
+            _elem374 = iprot.readString()
             self.authorizations.add(_elem374)
           iprot.readSetEnd()
         else:
@@ -13474,6 +16663,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.authorizations)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13548,6 +16744,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13590,17 +16792,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.password = iprot.readString();
+          self.password = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -13632,6 +16834,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.password)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13706,6 +16915,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13748,17 +16963,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.password = iprot.readString();
+          self.password = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -13790,6 +17005,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.password)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13864,6 +17086,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -13903,12 +17131,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -13936,6 +17164,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14010,6 +17244,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14049,12 +17289,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -14082,6 +17322,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14126,7 +17372,7 @@
           self.success = []
           (_etype379, _size376) = iprot.readListBegin()
           for _i380 in xrange(_size376):
-            _elem381 = iprot.readString();
+            _elem381 = iprot.readString()
             self.success.append(_elem381)
           iprot.readListEnd()
         else:
@@ -14175,6 +17421,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14217,17 +17470,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.I32:
-          self.perm = iprot.readI32();
+          self.perm = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -14259,6 +17512,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.perm)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14333,6 +17593,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14378,22 +17644,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.table = iprot.readString();
+          self.table = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.I32:
-          self.perm = iprot.readI32();
+          self.perm = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -14429,6 +17695,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.table)
+    value = (value * 31) ^ hash(self.perm)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14516,6 +17790,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14558,17 +17839,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.I32:
-          self.perm = iprot.readI32();
+          self.perm = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -14600,6 +17881,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.perm)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14641,7 +17929,7 @@
         break
       if fid == 0:
         if ftype == TType.BOOL:
-          self.success = iprot.readBool();
+          self.success = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -14685,6 +17973,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14730,22 +18025,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.table = iprot.readString();
+          self.table = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.I32:
-          self.perm = iprot.readI32();
+          self.perm = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -14781,6 +18076,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.table)
+    value = (value * 31) ^ hash(self.perm)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14825,7 +18128,7 @@
         break
       if fid == 0:
         if ftype == TType.BOOL:
-          self.success = iprot.readBool();
+          self.success = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -14879,6 +18182,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14915,7 +18226,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -14939,6 +18250,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -14986,7 +18302,7 @@
           self.success = set()
           (_etype386, _size383) = iprot.readSetBegin()
           for _i387 in xrange(_size383):
-            _elem388 = iprot.readString();
+            _elem388 = iprot.readString()
             self.success.add(_elem388)
           iprot.readSetEnd()
         else:
@@ -15045,6 +18361,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15087,17 +18411,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.I32:
-          self.perm = iprot.readI32();
+          self.perm = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -15129,6 +18453,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.perm)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15203,6 +18534,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15248,22 +18585,22 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.table = iprot.readString();
+          self.table = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.I32:
-          self.perm = iprot.readI32();
+          self.perm = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -15299,6 +18636,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.table)
+    value = (value * 31) ^ hash(self.perm)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15386,6 +18731,577 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class grantNamespacePermission_args:
+  """
+  Attributes:
+   - login
+   - user
+   - namespaceName
+   - perm
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'user', None, None, ), # 2
+    (3, TType.STRING, 'namespaceName', None, None, ), # 3
+    (4, TType.I32, 'perm', None, None, ), # 4
+  )
+
+  def __init__(self, login=None, user=None, namespaceName=None, perm=None,):
+    self.login = login
+    self.user = user
+    self.namespaceName = namespaceName
+    self.perm = perm
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.user = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.I32:
+          self.perm = iprot.readI32()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('grantNamespacePermission_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.user is not None:
+      oprot.writeFieldBegin('user', TType.STRING, 2)
+      oprot.writeString(self.user)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 3)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.perm is not None:
+      oprot.writeFieldBegin('perm', TType.I32, 4)
+      oprot.writeI32(self.perm)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.perm)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class grantNamespacePermission_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+  )
+
+  def __init__(self, ouch1=None, ouch2=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('grantNamespacePermission_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class hasNamespacePermission_args:
+  """
+  Attributes:
+   - login
+   - user
+   - namespaceName
+   - perm
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'user', None, None, ), # 2
+    (3, TType.STRING, 'namespaceName', None, None, ), # 3
+    (4, TType.I32, 'perm', None, None, ), # 4
+  )
+
+  def __init__(self, login=None, user=None, namespaceName=None, perm=None,):
+    self.login = login
+    self.user = user
+    self.namespaceName = namespaceName
+    self.perm = perm
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.user = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.I32:
+          self.perm = iprot.readI32()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('hasNamespacePermission_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.user is not None:
+      oprot.writeFieldBegin('user', TType.STRING, 2)
+      oprot.writeString(self.user)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 3)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.perm is not None:
+      oprot.writeFieldBegin('perm', TType.I32, 4)
+      oprot.writeI32(self.perm)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.perm)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class hasNamespacePermission_result:
+  """
+  Attributes:
+   - success
+   - ouch1
+   - ouch2
+  """
+
+  thrift_spec = (
+    (0, TType.BOOL, 'success', None, None, ), # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+  )
+
+  def __init__(self, success=None, ouch1=None, ouch2=None,):
+    self.success = success
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.BOOL:
+          self.success = iprot.readBool()
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('hasNamespacePermission_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.BOOL, 0)
+      oprot.writeBool(self.success)
+      oprot.writeFieldEnd()
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class revokeNamespacePermission_args:
+  """
+  Attributes:
+   - login
+   - user
+   - namespaceName
+   - perm
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'user', None, None, ), # 2
+    (3, TType.STRING, 'namespaceName', None, None, ), # 3
+    (4, TType.I32, 'perm', None, None, ), # 4
+  )
+
+  def __init__(self, login=None, user=None, namespaceName=None, perm=None,):
+    self.login = login
+    self.user = user
+    self.namespaceName = namespaceName
+    self.perm = perm
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.user = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.I32:
+          self.perm = iprot.readI32()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('revokeNamespacePermission_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.user is not None:
+      oprot.writeFieldBegin('user', TType.STRING, 2)
+      oprot.writeString(self.user)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 3)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.perm is not None:
+      oprot.writeFieldBegin('perm', TType.I32, 4)
+      oprot.writeI32(self.perm)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.perm)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class revokeNamespacePermission_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+  )
+
+  def __init__(self, ouch1=None, ouch2=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('revokeNamespacePermission_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15428,12 +19344,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -15471,6 +19387,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.options)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15515,7 +19438,7 @@
         break
       if fid == 0:
         if ftype == TType.STRING:
-          self.success = iprot.readString();
+          self.success = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -15569,6 +19492,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15611,12 +19542,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -15654,6 +19585,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.options)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15698,7 +19636,7 @@
         break
       if fid == 0:
         if ftype == TType.STRING:
-          self.success = iprot.readString();
+          self.success = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -15752,6 +19690,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15788,7 +19734,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.scanner = iprot.readString();
+          self.scanner = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -15812,6 +19758,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.scanner)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15850,7 +19801,7 @@
         break
       if fid == 0:
         if ftype == TType.BOOL:
-          self.success = iprot.readBool();
+          self.success = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -15884,6 +19835,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -15920,7 +19877,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.scanner = iprot.readString();
+          self.scanner = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -15944,6 +19901,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.scanner)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16043,6 +20005,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16082,12 +20052,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.scanner = iprot.readString();
+          self.scanner = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.I32:
-          self.k = iprot.readI32();
+          self.k = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -16115,6 +20085,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.scanner)
+    value = (value * 31) ^ hash(self.k)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16214,6 +20190,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16250,7 +20234,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.scanner = iprot.readString();
+          self.scanner = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -16274,6 +20258,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.scanner)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16335,6 +20324,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16377,12 +20371,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -16390,7 +20384,7 @@
           self.cells = {}
           (_ktype391, _vtype392, _size390 ) = iprot.readMapBegin()
           for _i394 in xrange(_size390):
-            _key395 = iprot.readString();
+            _key395 = iprot.readString()
             _val396 = []
             (_etype400, _size397) = iprot.readListBegin()
             for _i401 in xrange(_size397):
@@ -16438,6 +20432,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.cells)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16538,6 +20539,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.outch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    value = (value * 31) ^ hash(self.ouch4)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16580,12 +20589,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -16623,6 +20632,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.opts)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16667,7 +20683,7 @@
         break
       if fid == 0:
         if ftype == TType.STRING:
-          self.success = iprot.readString();
+          self.success = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -16721,6 +20737,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.outch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16760,7 +20784,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.writer = iprot.readString();
+          self.writer = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
@@ -16768,7 +20792,7 @@
           self.cells = {}
           (_ktype407, _vtype408, _size406 ) = iprot.readMapBegin()
           for _i410 in xrange(_size406):
-            _key411 = iprot.readString();
+            _key411 = iprot.readString()
             _val412 = []
             (_etype416, _size413) = iprot.readListBegin()
             for _i417 in xrange(_size413):
@@ -16812,6 +20836,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.writer)
+    value = (value * 31) ^ hash(self.cells)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16848,7 +20878,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.writer = iprot.readString();
+          self.writer = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -16872,6 +20902,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.writer)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16946,6 +20981,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -16982,7 +21023,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.writer = iprot.readString();
+          self.writer = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -17006,6 +21047,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.writer)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17080,6 +21126,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17125,17 +21177,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.row = iprot.readString();
+          self.row = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
@@ -17177,6 +21229,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.row)
+    value = (value * 31) ^ hash(self.updates)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17221,7 +21281,7 @@
         break
       if fid == 0:
         if ftype == TType.I32:
-          self.success = iprot.readI32();
+          self.success = iprot.readI32()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -17275,6 +21335,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17317,12 +21385,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.login = iprot.readString();
+          self.login = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.tableName = iprot.readString();
+          self.tableName = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -17360,6 +21428,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.tableName)
+    value = (value * 31) ^ hash(self.options)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17404,7 +21479,7 @@
         break
       if fid == 0:
         if ftype == TType.STRING:
-          self.success = iprot.readString();
+          self.success = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 1:
@@ -17458,6 +21533,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17497,7 +21580,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.conditionalWriter = iprot.readString();
+          self.conditionalWriter = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
@@ -17505,7 +21588,7 @@
           self.updates = {}
           (_ktype423, _vtype424, _size422 ) = iprot.readMapBegin()
           for _i426 in xrange(_size422):
-            _key427 = iprot.readString();
+            _key427 = iprot.readString()
             _val428 = ConditionalUpdates()
             _val428.read(iprot)
             self.updates[_key427] = _val428
@@ -17541,6 +21624,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.conditionalWriter)
+    value = (value * 31) ^ hash(self.updates)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17588,8 +21677,8 @@
           self.success = {}
           (_ktype432, _vtype433, _size431 ) = iprot.readMapBegin()
           for _i435 in xrange(_size431):
-            _key436 = iprot.readString();
-            _val437 = iprot.readI32();
+            _key436 = iprot.readString()
+            _val437 = iprot.readI32()
             self.success[_key436] = _val437
           iprot.readMapEnd()
         else:
@@ -17649,6 +21738,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17685,7 +21782,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.conditionalWriter = iprot.readString();
+          self.conditionalWriter = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -17709,6 +21806,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.conditionalWriter)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17751,6 +21853,10 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17787,7 +21893,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.row = iprot.readString();
+          self.row = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -17811,6 +21917,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.row)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17871,6 +21982,11 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -17916,7 +22032,7 @@
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.I32:
-          self.part = iprot.readI32();
+          self.part = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -17944,6 +22060,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.key)
+    value = (value * 31) ^ hash(self.part)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -18004,6 +22126,3686 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class systemNamespace_args:
+
+  thrift_spec = (
+  )
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('systemNamespace_args')
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class systemNamespace_result:
+  """
+  Attributes:
+   - success
+  """
+
+  thrift_spec = (
+    (0, TType.STRING, 'success', None, None, ), # 0
+  )
+
+  def __init__(self, success=None,):
+    self.success = success
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.STRING:
+          self.success = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('systemNamespace_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.STRING, 0)
+      oprot.writeString(self.success)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class defaultNamespace_args:
+
+  thrift_spec = (
+  )
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('defaultNamespace_args')
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class defaultNamespace_result:
+  """
+  Attributes:
+   - success
+  """
+
+  thrift_spec = (
+    (0, TType.STRING, 'success', None, None, ), # 0
+  )
+
+  def __init__(self, success=None,):
+    self.success = success
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.STRING:
+          self.success = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('defaultNamespace_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.STRING, 0)
+      oprot.writeString(self.success)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class listNamespaces_args:
+  """
+  Attributes:
+   - login
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+  )
+
+  def __init__(self, login=None,):
+    self.login = login
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('listNamespaces_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class listNamespaces_result:
+  """
+  Attributes:
+   - success
+   - ouch1
+   - ouch2
+  """
+
+  thrift_spec = (
+    (0, TType.LIST, 'success', (TType.STRING,None), None, ), # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+  )
+
+  def __init__(self, success=None, ouch1=None, ouch2=None,):
+    self.success = success
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.LIST:
+          self.success = []
+          (_etype443, _size440) = iprot.readListBegin()
+          for _i444 in xrange(_size440):
+            _elem445 = iprot.readString()
+            self.success.append(_elem445)
+          iprot.readListEnd()
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('listNamespaces_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.LIST, 0)
+      oprot.writeListBegin(TType.STRING, len(self.success))
+      for iter446 in self.success:
+        oprot.writeString(iter446)
+      oprot.writeListEnd()
+      oprot.writeFieldEnd()
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class namespaceExists_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+  )
+
+  def __init__(self, login=None, namespaceName=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('namespaceExists_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class namespaceExists_result:
+  """
+  Attributes:
+   - success
+   - ouch1
+   - ouch2
+  """
+
+  thrift_spec = (
+    (0, TType.BOOL, 'success', None, None, ), # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+  )
+
+  def __init__(self, success=None, ouch1=None, ouch2=None,):
+    self.success = success
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.BOOL:
+          self.success = iprot.readBool()
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('namespaceExists_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.BOOL, 0)
+      oprot.writeBool(self.success)
+      oprot.writeFieldEnd()
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class createNamespace_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+  )
+
+  def __init__(self, login=None, namespaceName=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('createNamespace_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class createNamespace_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceExistsException, NamespaceExistsException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, ouch1=None, ouch2=None, ouch3=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceExistsException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('createNamespace_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class deleteNamespace_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+  )
+
+  def __init__(self, login=None, namespaceName=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('deleteNamespace_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class deleteNamespace_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+   - ouch3
+   - ouch4
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+    (4, TType.STRUCT, 'ouch4', (NamespaceNotEmptyException, NamespaceNotEmptyException.thrift_spec), None, ), # 4
+  )
+
+  def __init__(self, ouch1=None, ouch2=None, ouch3=None, ouch4=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+    self.ouch4 = ouch4
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.STRUCT:
+          self.ouch4 = NamespaceNotEmptyException()
+          self.ouch4.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('deleteNamespace_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch4 is not None:
+      oprot.writeFieldBegin('ouch4', TType.STRUCT, 4)
+      self.ouch4.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    value = (value * 31) ^ hash(self.ouch4)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class renameNamespace_args:
+  """
+  Attributes:
+   - login
+   - oldNamespaceName
+   - newNamespaceName
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'oldNamespaceName', None, None, ), # 2
+    (3, TType.STRING, 'newNamespaceName', None, None, ), # 3
+  )
+
+  def __init__(self, login=None, oldNamespaceName=None, newNamespaceName=None,):
+    self.login = login
+    self.oldNamespaceName = oldNamespaceName
+    self.newNamespaceName = newNamespaceName
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.oldNamespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRING:
+          self.newNamespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('renameNamespace_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.oldNamespaceName is not None:
+      oprot.writeFieldBegin('oldNamespaceName', TType.STRING, 2)
+      oprot.writeString(self.oldNamespaceName)
+      oprot.writeFieldEnd()
+    if self.newNamespaceName is not None:
+      oprot.writeFieldBegin('newNamespaceName', TType.STRING, 3)
+      oprot.writeString(self.newNamespaceName)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.oldNamespaceName)
+    value = (value * 31) ^ hash(self.newNamespaceName)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class renameNamespace_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+   - ouch3
+   - ouch4
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+    (4, TType.STRUCT, 'ouch4', (NamespaceExistsException, NamespaceExistsException.thrift_spec), None, ), # 4
+  )
+
+  def __init__(self, ouch1=None, ouch2=None, ouch3=None, ouch4=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+    self.ouch4 = ouch4
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.STRUCT:
+          self.ouch4 = NamespaceExistsException()
+          self.ouch4.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('renameNamespace_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch4 is not None:
+      oprot.writeFieldBegin('ouch4', TType.STRUCT, 4)
+      self.ouch4.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    value = (value * 31) ^ hash(self.ouch4)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class setNamespaceProperty_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+   - property
+   - value
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+    (3, TType.STRING, 'property', None, None, ), # 3
+    (4, TType.STRING, 'value', None, None, ), # 4
+  )
+
+  def __init__(self, login=None, namespaceName=None, property=None, value=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+    self.property = property
+    self.value = value
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRING:
+          self.property = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.STRING:
+          self.value = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('setNamespaceProperty_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.property is not None:
+      oprot.writeFieldBegin('property', TType.STRING, 3)
+      oprot.writeString(self.property)
+      oprot.writeFieldEnd()
+    if self.value is not None:
+      oprot.writeFieldBegin('value', TType.STRING, 4)
+      oprot.writeString(self.value)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.property)
+    value = (value * 31) ^ hash(self.value)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class setNamespaceProperty_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, ouch1=None, ouch2=None, ouch3=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('setNamespaceProperty_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class removeNamespaceProperty_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+   - property
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+    (3, TType.STRING, 'property', None, None, ), # 3
+  )
+
+  def __init__(self, login=None, namespaceName=None, property=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+    self.property = property
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRING:
+          self.property = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('removeNamespaceProperty_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.property is not None:
+      oprot.writeFieldBegin('property', TType.STRING, 3)
+      oprot.writeString(self.property)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.property)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class removeNamespaceProperty_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, ouch1=None, ouch2=None, ouch3=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('removeNamespaceProperty_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class getNamespaceProperties_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+  )
+
+  def __init__(self, login=None, namespaceName=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('getNamespaceProperties_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class getNamespaceProperties_result:
+  """
+  Attributes:
+   - success
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    (0, TType.MAP, 'success', (TType.STRING,None,TType.STRING,None), None, ), # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, success=None, ouch1=None, ouch2=None, ouch3=None,):
+    self.success = success
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.MAP:
+          self.success = {}
+          (_ktype448, _vtype449, _size447 ) = iprot.readMapBegin()
+          for _i451 in xrange(_size447):
+            _key452 = iprot.readString()
+            _val453 = iprot.readString()
+            self.success[_key452] = _val453
+          iprot.readMapEnd()
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('getNamespaceProperties_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.MAP, 0)
+      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
+      for kiter454,viter455 in self.success.items():
+        oprot.writeString(kiter454)
+        oprot.writeString(viter455)
+      oprot.writeMapEnd()
+      oprot.writeFieldEnd()
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class namespaceIdMap_args:
+  """
+  Attributes:
+   - login
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+  )
+
+  def __init__(self, login=None,):
+    self.login = login
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('namespaceIdMap_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class namespaceIdMap_result:
+  """
+  Attributes:
+   - success
+   - ouch1
+   - ouch2
+  """
+
+  thrift_spec = (
+    (0, TType.MAP, 'success', (TType.STRING,None,TType.STRING,None), None, ), # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+  )
+
+  def __init__(self, success=None, ouch1=None, ouch2=None,):
+    self.success = success
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.MAP:
+          self.success = {}
+          (_ktype457, _vtype458, _size456 ) = iprot.readMapBegin()
+          for _i460 in xrange(_size456):
+            _key461 = iprot.readString()
+            _val462 = iprot.readString()
+            self.success[_key461] = _val462
+          iprot.readMapEnd()
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('namespaceIdMap_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.MAP, 0)
+      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
+      for kiter463,viter464 in self.success.items():
+        oprot.writeString(kiter463)
+        oprot.writeString(viter464)
+      oprot.writeMapEnd()
+      oprot.writeFieldEnd()
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class attachNamespaceIterator_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+   - setting
+   - scopes
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+    (3, TType.STRUCT, 'setting', (IteratorSetting, IteratorSetting.thrift_spec), None, ), # 3
+    (4, TType.SET, 'scopes', (TType.I32,None), None, ), # 4
+  )
+
+  def __init__(self, login=None, namespaceName=None, setting=None, scopes=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+    self.setting = setting
+    self.scopes = scopes
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.setting = IteratorSetting()
+          self.setting.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.SET:
+          self.scopes = set()
+          (_etype468, _size465) = iprot.readSetBegin()
+          for _i469 in xrange(_size465):
+            _elem470 = iprot.readI32()
+            self.scopes.add(_elem470)
+          iprot.readSetEnd()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('attachNamespaceIterator_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.setting is not None:
+      oprot.writeFieldBegin('setting', TType.STRUCT, 3)
+      self.setting.write(oprot)
+      oprot.writeFieldEnd()
+    if self.scopes is not None:
+      oprot.writeFieldBegin('scopes', TType.SET, 4)
+      oprot.writeSetBegin(TType.I32, len(self.scopes))
+      for iter471 in self.scopes:
+        oprot.writeI32(iter471)
+      oprot.writeSetEnd()
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.setting)
+    value = (value * 31) ^ hash(self.scopes)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class attachNamespaceIterator_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, ouch1=None, ouch2=None, ouch3=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('attachNamespaceIterator_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class removeNamespaceIterator_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+   - name
+   - scopes
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+    (3, TType.STRING, 'name', None, None, ), # 3
+    (4, TType.SET, 'scopes', (TType.I32,None), None, ), # 4
+  )
+
+  def __init__(self, login=None, namespaceName=None, name=None, scopes=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+    self.name = name
+    self.scopes = scopes
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRING:
+          self.name = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.SET:
+          self.scopes = set()
+          (_etype475, _size472) = iprot.readSetBegin()
+          for _i476 in xrange(_size472):
+            _elem477 = iprot.readI32()
+            self.scopes.add(_elem477)
+          iprot.readSetEnd()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('removeNamespaceIterator_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.name is not None:
+      oprot.writeFieldBegin('name', TType.STRING, 3)
+      oprot.writeString(self.name)
+      oprot.writeFieldEnd()
+    if self.scopes is not None:
+      oprot.writeFieldBegin('scopes', TType.SET, 4)
+      oprot.writeSetBegin(TType.I32, len(self.scopes))
+      for iter478 in self.scopes:
+        oprot.writeI32(iter478)
+      oprot.writeSetEnd()
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.name)
+    value = (value * 31) ^ hash(self.scopes)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class removeNamespaceIterator_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, ouch1=None, ouch2=None, ouch3=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('removeNamespaceIterator_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class getNamespaceIteratorSetting_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+   - name
+   - scope
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+    (3, TType.STRING, 'name', None, None, ), # 3
+    (4, TType.I32, 'scope', None, None, ), # 4
+  )
+
+  def __init__(self, login=None, namespaceName=None, name=None, scope=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+    self.name = name
+    self.scope = scope
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRING:
+          self.name = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.I32:
+          self.scope = iprot.readI32()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('getNamespaceIteratorSetting_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.name is not None:
+      oprot.writeFieldBegin('name', TType.STRING, 3)
+      oprot.writeString(self.name)
+      oprot.writeFieldEnd()
+    if self.scope is not None:
+      oprot.writeFieldBegin('scope', TType.I32, 4)
+      oprot.writeI32(self.scope)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.name)
+    value = (value * 31) ^ hash(self.scope)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class getNamespaceIteratorSetting_result:
+  """
+  Attributes:
+   - success
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    (0, TType.STRUCT, 'success', (IteratorSetting, IteratorSetting.thrift_spec), None, ), # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, success=None, ouch1=None, ouch2=None, ouch3=None,):
+    self.success = success
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.STRUCT:
+          self.success = IteratorSetting()
+          self.success.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('getNamespaceIteratorSetting_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.STRUCT, 0)
+      self.success.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class listNamespaceIterators_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+  )
+
+  def __init__(self, login=None, namespaceName=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('listNamespaceIterators_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class listNamespaceIterators_result:
+  """
+  Attributes:
+   - success
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    (0, TType.MAP, 'success', (TType.STRING,None,TType.SET,(TType.I32,None)), None, ), # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, success=None, ouch1=None, ouch2=None, ouch3=None,):
+    self.success = success
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.MAP:
+          self.success = {}
+          (_ktype480, _vtype481, _size479 ) = iprot.readMapBegin()
+          for _i483 in xrange(_size479):
+            _key484 = iprot.readString()
+            _val485 = set()
+            (_etype489, _size486) = iprot.readSetBegin()
+            for _i490 in xrange(_size486):
+              _elem491 = iprot.readI32()
+              _val485.add(_elem491)
+            iprot.readSetEnd()
+            self.success[_key484] = _val485
+          iprot.readMapEnd()
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('listNamespaceIterators_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.MAP, 0)
+      oprot.writeMapBegin(TType.STRING, TType.SET, len(self.success))
+      for kiter492,viter493 in self.success.items():
+        oprot.writeString(kiter492)
+        oprot.writeSetBegin(TType.I32, len(viter493))
+        for iter494 in viter493:
+          oprot.writeI32(iter494)
+        oprot.writeSetEnd()
+      oprot.writeMapEnd()
+      oprot.writeFieldEnd()
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class checkNamespaceIteratorConflicts_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+   - setting
+   - scopes
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+    (3, TType.STRUCT, 'setting', (IteratorSetting, IteratorSetting.thrift_spec), None, ), # 3
+    (4, TType.SET, 'scopes', (TType.I32,None), None, ), # 4
+  )
+
+  def __init__(self, login=None, namespaceName=None, setting=None, scopes=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+    self.setting = setting
+    self.scopes = scopes
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.setting = IteratorSetting()
+          self.setting.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.SET:
+          self.scopes = set()
+          (_etype498, _size495) = iprot.readSetBegin()
+          for _i499 in xrange(_size495):
+            _elem500 = iprot.readI32()
+            self.scopes.add(_elem500)
+          iprot.readSetEnd()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('checkNamespaceIteratorConflicts_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.setting is not None:
+      oprot.writeFieldBegin('setting', TType.STRUCT, 3)
+      self.setting.write(oprot)
+      oprot.writeFieldEnd()
+    if self.scopes is not None:
+      oprot.writeFieldBegin('scopes', TType.SET, 4)
+      oprot.writeSetBegin(TType.I32, len(self.scopes))
+      for iter501 in self.scopes:
+        oprot.writeI32(iter501)
+      oprot.writeSetEnd()
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.setting)
+    value = (value * 31) ^ hash(self.scopes)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class checkNamespaceIteratorConflicts_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, ouch1=None, ouch2=None, ouch3=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('checkNamespaceIteratorConflicts_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class addNamespaceConstraint_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+   - constraintClassName
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+    (3, TType.STRING, 'constraintClassName', None, None, ), # 3
+  )
+
+  def __init__(self, login=None, namespaceName=None, constraintClassName=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+    self.constraintClassName = constraintClassName
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRING:
+          self.constraintClassName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('addNamespaceConstraint_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.constraintClassName is not None:
+      oprot.writeFieldBegin('constraintClassName', TType.STRING, 3)
+      oprot.writeString(self.constraintClassName)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.constraintClassName)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class addNamespaceConstraint_result:
+  """
+  Attributes:
+   - success
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    (0, TType.I32, 'success', None, None, ), # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, success=None, ouch1=None, ouch2=None, ouch3=None,):
+    self.success = success
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.I32:
+          self.success = iprot.readI32()
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('addNamespaceConstraint_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.I32, 0)
+      oprot.writeI32(self.success)
+      oprot.writeFieldEnd()
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class removeNamespaceConstraint_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+   - id
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+    (3, TType.I32, 'id', None, None, ), # 3
+  )
+
+  def __init__(self, login=None, namespaceName=None, id=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+    self.id = id
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.I32:
+          self.id = iprot.readI32()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('removeNamespaceConstraint_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.id is not None:
+      oprot.writeFieldBegin('id', TType.I32, 3)
+      oprot.writeI32(self.id)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.id)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class removeNamespaceConstraint_result:
+  """
+  Attributes:
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, ouch1=None, ouch2=None, ouch3=None,):
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('removeNamespaceConstraint_result')
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class listNamespaceConstraints_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+  )
+
+  def __init__(self, login=None, namespaceName=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('listNamespaceConstraints_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class listNamespaceConstraints_result:
+  """
+  Attributes:
+   - success
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    (0, TType.MAP, 'success', (TType.STRING,None,TType.I32,None), None, ), # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, success=None, ouch1=None, ouch2=None, ouch3=None,):
+    self.success = success
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.MAP:
+          self.success = {}
+          (_ktype503, _vtype504, _size502 ) = iprot.readMapBegin()
+          for _i506 in xrange(_size502):
+            _key507 = iprot.readString()
+            _val508 = iprot.readI32()
+            self.success[_key507] = _val508
+          iprot.readMapEnd()
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('listNamespaceConstraints_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.MAP, 0)
+      oprot.writeMapBegin(TType.STRING, TType.I32, len(self.success))
+      for kiter509,viter510 in self.success.items():
+        oprot.writeString(kiter509)
+        oprot.writeI32(viter510)
+      oprot.writeMapEnd()
+      oprot.writeFieldEnd()
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class testNamespaceClassLoad_args:
+  """
+  Attributes:
+   - login
+   - namespaceName
+   - className
+   - asTypeName
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'login', None, None, ), # 1
+    (2, TType.STRING, 'namespaceName', None, None, ), # 2
+    (3, TType.STRING, 'className', None, None, ), # 3
+    (4, TType.STRING, 'asTypeName', None, None, ), # 4
+  )
+
+  def __init__(self, login=None, namespaceName=None, className=None, asTypeName=None,):
+    self.login = login
+    self.namespaceName = namespaceName
+    self.className = className
+    self.asTypeName = asTypeName
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.login = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.namespaceName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRING:
+          self.className = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      elif fid == 4:
+        if ftype == TType.STRING:
+          self.asTypeName = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('testNamespaceClassLoad_args')
+    if self.login is not None:
+      oprot.writeFieldBegin('login', TType.STRING, 1)
+      oprot.writeString(self.login)
+      oprot.writeFieldEnd()
+    if self.namespaceName is not None:
+      oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+      oprot.writeString(self.namespaceName)
+      oprot.writeFieldEnd()
+    if self.className is not None:
+      oprot.writeFieldBegin('className', TType.STRING, 3)
+      oprot.writeString(self.className)
+      oprot.writeFieldEnd()
+    if self.asTypeName is not None:
+      oprot.writeFieldBegin('asTypeName', TType.STRING, 4)
+      oprot.writeString(self.asTypeName)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.login)
+    value = (value * 31) ^ hash(self.namespaceName)
+    value = (value * 31) ^ hash(self.className)
+    value = (value * 31) ^ hash(self.asTypeName)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class testNamespaceClassLoad_result:
+  """
+  Attributes:
+   - success
+   - ouch1
+   - ouch2
+   - ouch3
+  """
+
+  thrift_spec = (
+    (0, TType.BOOL, 'success', None, None, ), # 0
+    (1, TType.STRUCT, 'ouch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
+    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
+    (3, TType.STRUCT, 'ouch3', (NamespaceNotFoundException, NamespaceNotFoundException.thrift_spec), None, ), # 3
+  )
+
+  def __init__(self, success=None, ouch1=None, ouch2=None, ouch3=None,):
+    self.success = success
+    self.ouch1 = ouch1
+    self.ouch2 = ouch2
+    self.ouch3 = ouch3
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 0:
+        if ftype == TType.BOOL:
+          self.success = iprot.readBool()
+        else:
+          iprot.skip(ftype)
+      elif fid == 1:
+        if ftype == TType.STRUCT:
+          self.ouch1 = AccumuloException()
+          self.ouch1.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRUCT:
+          self.ouch2 = AccumuloSecurityException()
+          self.ouch2.read(iprot)
+        else:
+          iprot.skip(ftype)
+      elif fid == 3:
+        if ftype == TType.STRUCT:
+          self.ouch3 = NamespaceNotFoundException()
+          self.ouch3.read(iprot)
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('testNamespaceClassLoad_result')
+    if self.success is not None:
+      oprot.writeFieldBegin('success', TType.BOOL, 0)
+      oprot.writeBool(self.success)
+      oprot.writeFieldEnd()
+    if self.ouch1 is not None:
+      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+      self.ouch1.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch2 is not None:
+      oprot.writeFieldBegin('ouch2', TType.STRUCT, 2)
+      self.ouch2.write(oprot)
+      oprot.writeFieldEnd()
+    if self.ouch3 is not None:
+      oprot.writeFieldBegin('ouch3', TType.STRUCT, 3)
+      self.ouch3.write(oprot)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.success)
+    value = (value * 31) ^ hash(self.ouch1)
+    value = (value * 31) ^ hash(self.ouch2)
+    value = (value * 31) ^ hash(self.ouch3)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
diff --git a/src/main/python/constants.py b/src/main/python/constants.py
index aea4826..8139236 100644
--- a/src/main/python/constants.py
+++ b/src/main/python/constants.py
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Autogenerated by Thrift Compiler (0.9.1)
+# Autogenerated by Thrift Compiler (0.9.3)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
diff --git a/src/main/python/ttypes.py b/src/main/python/ttypes.py
index a748c0a..3f9ec9c 100644
--- a/src/main/python/ttypes.py
+++ b/src/main/python/ttypes.py
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Autogenerated by Thrift Compiler (0.9.1)
+# Autogenerated by Thrift Compiler (0.9.3)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
@@ -126,6 +126,41 @@
     "OBTAIN_DELEGATION_TOKEN": 11,
   }
 
+class NamespacePermission:
+  READ = 0
+  WRITE = 1
+  ALTER_NAMESPACE = 2
+  GRANT = 3
+  ALTER_TABLE = 4
+  CREATE_TABLE = 5
+  DROP_TABLE = 6
+  BULK_IMPORT = 7
+  DROP_NAMESPACE = 8
+
+  _VALUES_TO_NAMES = {
+    0: "READ",
+    1: "WRITE",
+    2: "ALTER_NAMESPACE",
+    3: "GRANT",
+    4: "ALTER_TABLE",
+    5: "CREATE_TABLE",
+    6: "DROP_TABLE",
+    7: "BULK_IMPORT",
+    8: "DROP_NAMESPACE",
+  }
+
+  _NAMES_TO_VALUES = {
+    "READ": 0,
+    "WRITE": 1,
+    "ALTER_NAMESPACE": 2,
+    "GRANT": 3,
+    "ALTER_TABLE": 4,
+    "CREATE_TABLE": 5,
+    "DROP_TABLE": 6,
+    "BULK_IMPORT": 7,
+    "DROP_NAMESPACE": 8,
+  }
+
 class ScanType:
   SINGLE = 0
   BATCH = 1
@@ -315,27 +350,27 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.row = iprot.readString();
+          self.row = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.colFamily = iprot.readString();
+          self.colFamily = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.colQualifier = iprot.readString();
+          self.colQualifier = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.STRING:
-          self.colVisibility = iprot.readString();
+          self.colVisibility = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.I64:
-          self.timestamp = iprot.readI64();
+          self.timestamp = iprot.readI64()
         else:
           iprot.skip(ftype)
       else:
@@ -375,6 +410,15 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.row)
+    value = (value * 31) ^ hash(self.colFamily)
+    value = (value * 31) ^ hash(self.colQualifier)
+    value = (value * 31) ^ hash(self.colVisibility)
+    value = (value * 31) ^ hash(self.timestamp)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -426,32 +470,32 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.colFamily = iprot.readString();
+          self.colFamily = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.colQualifier = iprot.readString();
+          self.colQualifier = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.colVisibility = iprot.readString();
+          self.colVisibility = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.I64:
-          self.timestamp = iprot.readI64();
+          self.timestamp = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.STRING:
-          self.value = iprot.readString();
+          self.value = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 6:
         if ftype == TType.BOOL:
-          self.deleteCell = iprot.readBool();
+          self.deleteCell = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -495,6 +539,16 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.colFamily)
+    value = (value * 31) ^ hash(self.colQualifier)
+    value = (value * 31) ^ hash(self.colVisibility)
+    value = (value * 31) ^ hash(self.timestamp)
+    value = (value * 31) ^ hash(self.value)
+    value = (value * 31) ^ hash(self.deleteCell)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -537,14 +591,14 @@
           self.tables = []
           (_etype3, _size0) = iprot.readListBegin()
           for _i4 in xrange(_size0):
-            _elem5 = iprot.readString();
+            _elem5 = iprot.readString()
             self.tables.append(_elem5)
           iprot.readListEnd()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.I64:
-          self.usage = iprot.readI64();
+          self.usage = iprot.readI64()
         else:
           iprot.skip(ftype)
       else:
@@ -575,6 +629,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.tables)
+    value = (value * 31) ^ hash(self.usage)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -620,7 +680,7 @@
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.value = iprot.readString();
+          self.value = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -648,6 +708,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.key)
+    value = (value * 31) ^ hash(self.value)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -698,7 +764,7 @@
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.BOOL:
-          self.more = iprot.readBool();
+          self.more = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -729,6 +795,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.results)
+    value = (value * 31) ^ hash(self.more)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -780,7 +852,7 @@
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.BOOL:
-          self.startInclusive = iprot.readBool();
+          self.startInclusive = iprot.readBool()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -791,7 +863,7 @@
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.BOOL:
-          self.stopInclusive = iprot.readBool();
+          self.stopInclusive = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -827,6 +899,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.start)
+    value = (value * 31) ^ hash(self.startInclusive)
+    value = (value * 31) ^ hash(self.stop)
+    value = (value * 31) ^ hash(self.stopInclusive)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -866,12 +946,12 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.colFamily = iprot.readString();
+          self.colFamily = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.colQualifier = iprot.readString();
+          self.colQualifier = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -899,6 +979,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.colFamily)
+    value = (value * 31) ^ hash(self.colQualifier)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -944,17 +1030,17 @@
         break
       if fid == 1:
         if ftype == TType.I32:
-          self.priority = iprot.readI32();
+          self.priority = iprot.readI32()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.name = iprot.readString();
+          self.name = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.iteratorClass = iprot.readString();
+          self.iteratorClass = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
@@ -962,8 +1048,8 @@
           self.properties = {}
           (_ktype15, _vtype16, _size14 ) = iprot.readMapBegin()
           for _i18 in xrange(_size14):
-            _key19 = iprot.readString();
-            _val20 = iprot.readString();
+            _key19 = iprot.readString()
+            _val20 = iprot.readString()
             self.properties[_key19] = _val20
           iprot.readMapEnd()
         else:
@@ -1005,6 +1091,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.priority)
+    value = (value * 31) ^ hash(self.name)
+    value = (value * 31) ^ hash(self.iteratorClass)
+    value = (value * 31) ^ hash(self.properties)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -1056,7 +1150,7 @@
           self.authorizations = set()
           (_etype26, _size23) = iprot.readSetBegin()
           for _i27 in xrange(_size23):
-            _elem28 = iprot.readString();
+            _elem28 = iprot.readString()
             self.authorizations.add(_elem28)
           iprot.readSetEnd()
         else:
@@ -1091,7 +1185,7 @@
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.I32:
-          self.bufferSize = iprot.readI32();
+          self.bufferSize = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -1140,6 +1234,15 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.authorizations)
+    value = (value * 31) ^ hash(self.range)
+    value = (value * 31) ^ hash(self.columns)
+    value = (value * 31) ^ hash(self.iterators)
+    value = (value * 31) ^ hash(self.bufferSize)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -1191,7 +1294,7 @@
           self.authorizations = set()
           (_etype47, _size44) = iprot.readSetBegin()
           for _i48 in xrange(_size44):
-            _elem49 = iprot.readString();
+            _elem49 = iprot.readString()
             self.authorizations.add(_elem49)
           iprot.readSetEnd()
         else:
@@ -1231,7 +1334,7 @@
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.I32:
-          self.threads = iprot.readI32();
+          self.threads = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -1283,6 +1386,15 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.authorizations)
+    value = (value * 31) ^ hash(self.ranges)
+    value = (value * 31) ^ hash(self.columns)
+    value = (value * 31) ^ hash(self.iterators)
+    value = (value * 31) ^ hash(self.threads)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -1328,7 +1440,7 @@
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.BOOL:
-          self.hasNext = iprot.readBool();
+          self.hasNext = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -1356,6 +1468,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.keyValue)
+    value = (value * 31) ^ hash(self.hasNext)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -1398,17 +1516,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.tableId = iprot.readString();
+          self.tableId = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.endRow = iprot.readString();
+          self.endRow = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.prevEndRow = iprot.readString();
+          self.prevEndRow = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -1440,6 +1558,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.tableId)
+    value = (value * 31) ^ hash(self.endRow)
+    value = (value * 31) ^ hash(self.prevEndRow)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -1482,17 +1607,17 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.colFamily = iprot.readString();
+          self.colFamily = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.colQualifier = iprot.readString();
+          self.colQualifier = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.colVisibility = iprot.readString();
+          self.colVisibility = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -1524,6 +1649,13 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.colFamily)
+    value = (value * 31) ^ hash(self.colQualifier)
+    value = (value * 31) ^ hash(self.colVisibility)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -1575,12 +1707,12 @@
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.I64:
-          self.timestamp = iprot.readI64();
+          self.timestamp = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.value = iprot.readString();
+          self.value = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
@@ -1630,6 +1762,14 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.column)
+    value = (value * 31) ^ hash(self.timestamp)
+    value = (value * 31) ^ hash(self.value)
+    value = (value * 31) ^ hash(self.iterators)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -1721,6 +1861,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.conditions)
+    value = (value * 31) ^ hash(self.updates)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -1769,17 +1915,17 @@
         break
       if fid == 1:
         if ftype == TType.I64:
-          self.maxMemory = iprot.readI64();
+          self.maxMemory = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.I64:
-          self.timeoutMs = iprot.readI64();
+          self.timeoutMs = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.I32:
-          self.threads = iprot.readI32();
+          self.threads = iprot.readI32()
         else:
           iprot.skip(ftype)
       elif fid == 4:
@@ -1787,14 +1933,14 @@
           self.authorizations = set()
           (_etype96, _size93) = iprot.readSetBegin()
           for _i97 in xrange(_size93):
-            _elem98 = iprot.readString();
+            _elem98 = iprot.readString()
             self.authorizations.add(_elem98)
           iprot.readSetEnd()
         else:
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.I32:
-          self.durability = iprot.readI32();
+          self.durability = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -1837,6 +1983,15 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.maxMemory)
+    value = (value * 31) ^ hash(self.timeoutMs)
+    value = (value * 31) ^ hash(self.threads)
+    value = (value * 31) ^ hash(self.authorizations)
+    value = (value * 31) ^ hash(self.durability)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -1903,37 +2058,37 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.client = iprot.readString();
+          self.client = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.user = iprot.readString();
+          self.user = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.STRING:
-          self.table = iprot.readString();
+          self.table = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.I64:
-          self.age = iprot.readI64();
+          self.age = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.I64:
-          self.idleTime = iprot.readI64();
+          self.idleTime = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 6:
         if ftype == TType.I32:
-          self.type = iprot.readI32();
+          self.type = iprot.readI32()
         else:
           iprot.skip(ftype)
       elif fid == 7:
         if ftype == TType.I32:
-          self.state = iprot.readI32();
+          self.state = iprot.readI32()
         else:
           iprot.skip(ftype)
       elif fid == 8:
@@ -1969,7 +2124,7 @@
           self.authorizations = []
           (_etype115, _size112) = iprot.readListBegin()
           for _i116 in xrange(_size112):
-            _elem117 = iprot.readString();
+            _elem117 = iprot.readString()
             self.authorizations.append(_elem117)
           iprot.readListEnd()
         else:
@@ -2044,6 +2199,21 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.client)
+    value = (value * 31) ^ hash(self.user)
+    value = (value * 31) ^ hash(self.table)
+    value = (value * 31) ^ hash(self.age)
+    value = (value * 31) ^ hash(self.idleTime)
+    value = (value * 31) ^ hash(self.type)
+    value = (value * 31) ^ hash(self.state)
+    value = (value * 31) ^ hash(self.extent)
+    value = (value * 31) ^ hash(self.columns)
+    value = (value * 31) ^ hash(self.iterators)
+    value = (value * 31) ^ hash(self.authorizations)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2113,7 +2283,7 @@
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.I64:
-          self.age = iprot.readI64();
+          self.age = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 3:
@@ -2121,39 +2291,39 @@
           self.inputFiles = []
           (_etype124, _size121) = iprot.readListBegin()
           for _i125 in xrange(_size121):
-            _elem126 = iprot.readString();
+            _elem126 = iprot.readString()
             self.inputFiles.append(_elem126)
           iprot.readListEnd()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.STRING:
-          self.outputFile = iprot.readString();
+          self.outputFile = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.I32:
-          self.type = iprot.readI32();
+          self.type = iprot.readI32()
         else:
           iprot.skip(ftype)
       elif fid == 6:
         if ftype == TType.I32:
-          self.reason = iprot.readI32();
+          self.reason = iprot.readI32()
         else:
           iprot.skip(ftype)
       elif fid == 7:
         if ftype == TType.STRING:
-          self.localityGroup = iprot.readString();
+          self.localityGroup = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 8:
         if ftype == TType.I64:
-          self.entriesRead = iprot.readI64();
+          self.entriesRead = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 9:
         if ftype == TType.I64:
-          self.entriesWritten = iprot.readI64();
+          self.entriesWritten = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 10:
@@ -2230,6 +2400,20 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.extent)
+    value = (value * 31) ^ hash(self.age)
+    value = (value * 31) ^ hash(self.inputFiles)
+    value = (value * 31) ^ hash(self.outputFile)
+    value = (value * 31) ^ hash(self.type)
+    value = (value * 31) ^ hash(self.reason)
+    value = (value * 31) ^ hash(self.localityGroup)
+    value = (value * 31) ^ hash(self.entriesRead)
+    value = (value * 31) ^ hash(self.entriesWritten)
+    value = (value * 31) ^ hash(self.iterators)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2278,27 +2462,27 @@
         break
       if fid == 1:
         if ftype == TType.I64:
-          self.maxMemory = iprot.readI64();
+          self.maxMemory = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.I64:
-          self.latencyMs = iprot.readI64();
+          self.latencyMs = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 3:
         if ftype == TType.I64:
-          self.timeoutMs = iprot.readI64();
+          self.timeoutMs = iprot.readI64()
         else:
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.I32:
-          self.threads = iprot.readI32();
+          self.threads = iprot.readI32()
         else:
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.I32:
-          self.durability = iprot.readI32();
+          self.durability = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -2338,6 +2522,15 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.maxMemory)
+    value = (value * 31) ^ hash(self.latencyMs)
+    value = (value * 31) ^ hash(self.timeoutMs)
+    value = (value * 31) ^ hash(self.threads)
+    value = (value * 31) ^ hash(self.durability)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2377,7 +2570,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.className = iprot.readString();
+          self.className = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
@@ -2385,8 +2578,8 @@
           self.options = {}
           (_ktype136, _vtype137, _size135 ) = iprot.readMapBegin()
           for _i139 in xrange(_size135):
-            _key140 = iprot.readString();
-            _val141 = iprot.readString();
+            _key140 = iprot.readString()
+            _val141 = iprot.readString()
             self.options[_key140] = _val141
           iprot.readMapEnd()
         else:
@@ -2420,6 +2613,12 @@
     return
 
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.className)
+    value = (value * 31) ^ hash(self.options)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2456,7 +2655,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2483,6 +2682,11 @@
   def __str__(self):
     return repr(self)
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2519,7 +2723,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2546,6 +2750,11 @@
   def __str__(self):
     return repr(self)
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2582,7 +2791,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2609,6 +2818,11 @@
   def __str__(self):
     return repr(self)
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2645,7 +2859,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2672,6 +2886,11 @@
   def __str__(self):
     return repr(self)
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2708,7 +2927,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2735,6 +2954,11 @@
   def __str__(self):
     return repr(self)
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2771,7 +2995,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2798,6 +3022,11 @@
   def __str__(self):
     return repr(self)
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2834,7 +3063,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2861,6 +3090,11 @@
   def __str__(self):
     return repr(self)
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
@@ -2897,7 +3131,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2924,6 +3158,215 @@
   def __str__(self):
     return repr(self)
 
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class NamespaceExistsException(TException):
+  """
+  Attributes:
+   - msg
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'msg', None, None, ), # 1
+  )
+
+  def __init__(self, msg=None,):
+    self.msg = msg
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.msg = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('NamespaceExistsException')
+    if self.msg is not None:
+      oprot.writeFieldBegin('msg', TType.STRING, 1)
+      oprot.writeString(self.msg)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __str__(self):
+    return repr(self)
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class NamespaceNotFoundException(TException):
+  """
+  Attributes:
+   - msg
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'msg', None, None, ), # 1
+  )
+
+  def __init__(self, msg=None,):
+    self.msg = msg
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.msg = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('NamespaceNotFoundException')
+    if self.msg is not None:
+      oprot.writeFieldBegin('msg', TType.STRING, 1)
+      oprot.writeString(self.msg)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __str__(self):
+    return repr(self)
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
+  def __repr__(self):
+    L = ['%s=%r' % (key, value)
+      for key, value in self.__dict__.iteritems()]
+    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+
+  def __eq__(self, other):
+    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+
+  def __ne__(self, other):
+    return not (self == other)
+
+class NamespaceNotEmptyException(TException):
+  """
+  Attributes:
+   - msg
+  """
+
+  thrift_spec = (
+    None, # 0
+    (1, TType.STRING, 'msg', None, None, ), # 1
+  )
+
+  def __init__(self, msg=None,):
+    self.msg = msg
+
+  def read(self, iprot):
+    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
+      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
+      return
+    iprot.readStructBegin()
+    while True:
+      (fname, ftype, fid) = iprot.readFieldBegin()
+      if ftype == TType.STOP:
+        break
+      if fid == 1:
+        if ftype == TType.STRING:
+          self.msg = iprot.readString()
+        else:
+          iprot.skip(ftype)
+      else:
+        iprot.skip(ftype)
+      iprot.readFieldEnd()
+    iprot.readStructEnd()
+
+  def write(self, oprot):
+    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
+      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
+      return
+    oprot.writeStructBegin('NamespaceNotEmptyException')
+    if self.msg is not None:
+      oprot.writeFieldBegin('msg', TType.STRING, 1)
+      oprot.writeString(self.msg)
+      oprot.writeFieldEnd()
+    oprot.writeFieldStop()
+    oprot.writeStructEnd()
+
+  def validate(self):
+    return
+
+
+  def __str__(self):
+    return repr(self)
+
+  def __hash__(self):
+    value = 17
+    value = (value * 31) ^ hash(self.msg)
+    return value
+
   def __repr__(self):
     L = ['%s=%r' % (key, value)
       for key, value in self.__dict__.iteritems()]
diff --git a/src/main/ruby/accumulo_proxy.rb b/src/main/ruby/accumulo_proxy.rb
index f8d892e..e02ba16 100644
--- a/src/main/ruby/accumulo_proxy.rb
+++ b/src/main/ruby/accumulo_proxy.rb
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Autogenerated by Thrift Compiler (0.9.1)
+# Autogenerated by Thrift Compiler (0.9.3)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
@@ -1041,6 +1041,55 @@
         return
       end
 
+      def grantNamespacePermission(login, user, namespaceName, perm)
+        send_grantNamespacePermission(login, user, namespaceName, perm)
+        recv_grantNamespacePermission()
+      end
+
+      def send_grantNamespacePermission(login, user, namespaceName, perm)
+        send_message('grantNamespacePermission', GrantNamespacePermission_args, :login => login, :user => user, :namespaceName => namespaceName, :perm => perm)
+      end
+
+      def recv_grantNamespacePermission()
+        result = receive_message(GrantNamespacePermission_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        return
+      end
+
+      def hasNamespacePermission(login, user, namespaceName, perm)
+        send_hasNamespacePermission(login, user, namespaceName, perm)
+        return recv_hasNamespacePermission()
+      end
+
+      def send_hasNamespacePermission(login, user, namespaceName, perm)
+        send_message('hasNamespacePermission', HasNamespacePermission_args, :login => login, :user => user, :namespaceName => namespaceName, :perm => perm)
+      end
+
+      def recv_hasNamespacePermission()
+        result = receive_message(HasNamespacePermission_result)
+        return result.success unless result.success.nil?
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'hasNamespacePermission failed: unknown result')
+      end
+
+      def revokeNamespacePermission(login, user, namespaceName, perm)
+        send_revokeNamespacePermission(login, user, namespaceName, perm)
+        recv_revokeNamespacePermission()
+      end
+
+      def send_revokeNamespacePermission(login, user, namespaceName, perm)
+        send_message('revokeNamespacePermission', RevokeNamespacePermission_args, :login => login, :user => user, :namespaceName => namespaceName, :perm => perm)
+      end
+
+      def recv_revokeNamespacePermission()
+        result = receive_message(RevokeNamespacePermission_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        return
+      end
+
       def createBatchScanner(login, tableName, options)
         send_createBatchScanner(login, tableName, options)
         return recv_createBatchScanner()
@@ -1185,7 +1234,7 @@
       end
 
       def send_update(writer, cells)
-        send_message('update', Update_args, :writer => writer, :cells => cells)
+        send_oneway_message('update', Update_args, :writer => writer, :cells => cells)
       end
       def flush(writer)
         send_flush(writer)
@@ -1317,6 +1366,350 @@
         raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getFollowing failed: unknown result')
       end
 
+      def systemNamespace()
+        send_systemNamespace()
+        return recv_systemNamespace()
+      end
+
+      def send_systemNamespace()
+        send_message('systemNamespace', SystemNamespace_args)
+      end
+
+      def recv_systemNamespace()
+        result = receive_message(SystemNamespace_result)
+        return result.success unless result.success.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'systemNamespace failed: unknown result')
+      end
+
+      def defaultNamespace()
+        send_defaultNamespace()
+        return recv_defaultNamespace()
+      end
+
+      def send_defaultNamespace()
+        send_message('defaultNamespace', DefaultNamespace_args)
+      end
+
+      def recv_defaultNamespace()
+        result = receive_message(DefaultNamespace_result)
+        return result.success unless result.success.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'defaultNamespace failed: unknown result')
+      end
+
+      def listNamespaces(login)
+        send_listNamespaces(login)
+        return recv_listNamespaces()
+      end
+
+      def send_listNamespaces(login)
+        send_message('listNamespaces', ListNamespaces_args, :login => login)
+      end
+
+      def recv_listNamespaces()
+        result = receive_message(ListNamespaces_result)
+        return result.success unless result.success.nil?
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'listNamespaces failed: unknown result')
+      end
+
+      def namespaceExists(login, namespaceName)
+        send_namespaceExists(login, namespaceName)
+        return recv_namespaceExists()
+      end
+
+      def send_namespaceExists(login, namespaceName)
+        send_message('namespaceExists', NamespaceExists_args, :login => login, :namespaceName => namespaceName)
+      end
+
+      def recv_namespaceExists()
+        result = receive_message(NamespaceExists_result)
+        return result.success unless result.success.nil?
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'namespaceExists failed: unknown result')
+      end
+
+      def createNamespace(login, namespaceName)
+        send_createNamespace(login, namespaceName)
+        recv_createNamespace()
+      end
+
+      def send_createNamespace(login, namespaceName)
+        send_message('createNamespace', CreateNamespace_args, :login => login, :namespaceName => namespaceName)
+      end
+
+      def recv_createNamespace()
+        result = receive_message(CreateNamespace_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        return
+      end
+
+      def deleteNamespace(login, namespaceName)
+        send_deleteNamespace(login, namespaceName)
+        recv_deleteNamespace()
+      end
+
+      def send_deleteNamespace(login, namespaceName)
+        send_message('deleteNamespace', DeleteNamespace_args, :login => login, :namespaceName => namespaceName)
+      end
+
+      def recv_deleteNamespace()
+        result = receive_message(DeleteNamespace_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        raise result.ouch4 unless result.ouch4.nil?
+        return
+      end
+
+      def renameNamespace(login, oldNamespaceName, newNamespaceName)
+        send_renameNamespace(login, oldNamespaceName, newNamespaceName)
+        recv_renameNamespace()
+      end
+
+      def send_renameNamespace(login, oldNamespaceName, newNamespaceName)
+        send_message('renameNamespace', RenameNamespace_args, :login => login, :oldNamespaceName => oldNamespaceName, :newNamespaceName => newNamespaceName)
+      end
+
+      def recv_renameNamespace()
+        result = receive_message(RenameNamespace_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        raise result.ouch4 unless result.ouch4.nil?
+        return
+      end
+
+      def setNamespaceProperty(login, namespaceName, property, value)
+        send_setNamespaceProperty(login, namespaceName, property, value)
+        recv_setNamespaceProperty()
+      end
+
+      def send_setNamespaceProperty(login, namespaceName, property, value)
+        send_message('setNamespaceProperty', SetNamespaceProperty_args, :login => login, :namespaceName => namespaceName, :property => property, :value => value)
+      end
+
+      def recv_setNamespaceProperty()
+        result = receive_message(SetNamespaceProperty_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        return
+      end
+
+      def removeNamespaceProperty(login, namespaceName, property)
+        send_removeNamespaceProperty(login, namespaceName, property)
+        recv_removeNamespaceProperty()
+      end
+
+      def send_removeNamespaceProperty(login, namespaceName, property)
+        send_message('removeNamespaceProperty', RemoveNamespaceProperty_args, :login => login, :namespaceName => namespaceName, :property => property)
+      end
+
+      def recv_removeNamespaceProperty()
+        result = receive_message(RemoveNamespaceProperty_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        return
+      end
+
+      def getNamespaceProperties(login, namespaceName)
+        send_getNamespaceProperties(login, namespaceName)
+        return recv_getNamespaceProperties()
+      end
+
+      def send_getNamespaceProperties(login, namespaceName)
+        send_message('getNamespaceProperties', GetNamespaceProperties_args, :login => login, :namespaceName => namespaceName)
+      end
+
+      def recv_getNamespaceProperties()
+        result = receive_message(GetNamespaceProperties_result)
+        return result.success unless result.success.nil?
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getNamespaceProperties failed: unknown result')
+      end
+
+      def namespaceIdMap(login)
+        send_namespaceIdMap(login)
+        return recv_namespaceIdMap()
+      end
+
+      def send_namespaceIdMap(login)
+        send_message('namespaceIdMap', NamespaceIdMap_args, :login => login)
+      end
+
+      def recv_namespaceIdMap()
+        result = receive_message(NamespaceIdMap_result)
+        return result.success unless result.success.nil?
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'namespaceIdMap failed: unknown result')
+      end
+
+      def attachNamespaceIterator(login, namespaceName, setting, scopes)
+        send_attachNamespaceIterator(login, namespaceName, setting, scopes)
+        recv_attachNamespaceIterator()
+      end
+
+      def send_attachNamespaceIterator(login, namespaceName, setting, scopes)
+        send_message('attachNamespaceIterator', AttachNamespaceIterator_args, :login => login, :namespaceName => namespaceName, :setting => setting, :scopes => scopes)
+      end
+
+      def recv_attachNamespaceIterator()
+        result = receive_message(AttachNamespaceIterator_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        return
+      end
+
+      def removeNamespaceIterator(login, namespaceName, name, scopes)
+        send_removeNamespaceIterator(login, namespaceName, name, scopes)
+        recv_removeNamespaceIterator()
+      end
+
+      def send_removeNamespaceIterator(login, namespaceName, name, scopes)
+        send_message('removeNamespaceIterator', RemoveNamespaceIterator_args, :login => login, :namespaceName => namespaceName, :name => name, :scopes => scopes)
+      end
+
+      def recv_removeNamespaceIterator()
+        result = receive_message(RemoveNamespaceIterator_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        return
+      end
+
+      def getNamespaceIteratorSetting(login, namespaceName, name, scope)
+        send_getNamespaceIteratorSetting(login, namespaceName, name, scope)
+        return recv_getNamespaceIteratorSetting()
+      end
+
+      def send_getNamespaceIteratorSetting(login, namespaceName, name, scope)
+        send_message('getNamespaceIteratorSetting', GetNamespaceIteratorSetting_args, :login => login, :namespaceName => namespaceName, :name => name, :scope => scope)
+      end
+
+      def recv_getNamespaceIteratorSetting()
+        result = receive_message(GetNamespaceIteratorSetting_result)
+        return result.success unless result.success.nil?
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'getNamespaceIteratorSetting failed: unknown result')
+      end
+
+      def listNamespaceIterators(login, namespaceName)
+        send_listNamespaceIterators(login, namespaceName)
+        return recv_listNamespaceIterators()
+      end
+
+      def send_listNamespaceIterators(login, namespaceName)
+        send_message('listNamespaceIterators', ListNamespaceIterators_args, :login => login, :namespaceName => namespaceName)
+      end
+
+      def recv_listNamespaceIterators()
+        result = receive_message(ListNamespaceIterators_result)
+        return result.success unless result.success.nil?
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'listNamespaceIterators failed: unknown result')
+      end
+
+      def checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes)
+        send_checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes)
+        recv_checkNamespaceIteratorConflicts()
+      end
+
+      def send_checkNamespaceIteratorConflicts(login, namespaceName, setting, scopes)
+        send_message('checkNamespaceIteratorConflicts', CheckNamespaceIteratorConflicts_args, :login => login, :namespaceName => namespaceName, :setting => setting, :scopes => scopes)
+      end
+
+      def recv_checkNamespaceIteratorConflicts()
+        result = receive_message(CheckNamespaceIteratorConflicts_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        return
+      end
+
+      def addNamespaceConstraint(login, namespaceName, constraintClassName)
+        send_addNamespaceConstraint(login, namespaceName, constraintClassName)
+        return recv_addNamespaceConstraint()
+      end
+
+      def send_addNamespaceConstraint(login, namespaceName, constraintClassName)
+        send_message('addNamespaceConstraint', AddNamespaceConstraint_args, :login => login, :namespaceName => namespaceName, :constraintClassName => constraintClassName)
+      end
+
+      def recv_addNamespaceConstraint()
+        result = receive_message(AddNamespaceConstraint_result)
+        return result.success unless result.success.nil?
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'addNamespaceConstraint failed: unknown result')
+      end
+
+      def removeNamespaceConstraint(login, namespaceName, id)
+        send_removeNamespaceConstraint(login, namespaceName, id)
+        recv_removeNamespaceConstraint()
+      end
+
+      def send_removeNamespaceConstraint(login, namespaceName, id)
+        send_message('removeNamespaceConstraint', RemoveNamespaceConstraint_args, :login => login, :namespaceName => namespaceName, :id => id)
+      end
+
+      def recv_removeNamespaceConstraint()
+        result = receive_message(RemoveNamespaceConstraint_result)
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        return
+      end
+
+      def listNamespaceConstraints(login, namespaceName)
+        send_listNamespaceConstraints(login, namespaceName)
+        return recv_listNamespaceConstraints()
+      end
+
+      def send_listNamespaceConstraints(login, namespaceName)
+        send_message('listNamespaceConstraints', ListNamespaceConstraints_args, :login => login, :namespaceName => namespaceName)
+      end
+
+      def recv_listNamespaceConstraints()
+        result = receive_message(ListNamespaceConstraints_result)
+        return result.success unless result.success.nil?
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'listNamespaceConstraints failed: unknown result')
+      end
+
+      def testNamespaceClassLoad(login, namespaceName, className, asTypeName)
+        send_testNamespaceClassLoad(login, namespaceName, className, asTypeName)
+        return recv_testNamespaceClassLoad()
+      end
+
+      def send_testNamespaceClassLoad(login, namespaceName, className, asTypeName)
+        send_message('testNamespaceClassLoad', TestNamespaceClassLoad_args, :login => login, :namespaceName => namespaceName, :className => className, :asTypeName => asTypeName)
+      end
+
+      def recv_testNamespaceClassLoad()
+        result = receive_message(TestNamespaceClassLoad_result)
+        return result.success unless result.success.nil?
+        raise result.ouch1 unless result.ouch1.nil?
+        raise result.ouch2 unless result.ouch2.nil?
+        raise result.ouch3 unless result.ouch3.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'testNamespaceClassLoad failed: unknown result')
+      end
+
     end
 
     class Processor
@@ -2152,6 +2545,45 @@
         write_result(result, oprot, 'revokeTablePermission', seqid)
       end
 
+      def process_grantNamespacePermission(seqid, iprot, oprot)
+        args = read_args(iprot, GrantNamespacePermission_args)
+        result = GrantNamespacePermission_result.new()
+        begin
+          @handler.grantNamespacePermission(args.login, args.user, args.namespaceName, args.perm)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        end
+        write_result(result, oprot, 'grantNamespacePermission', seqid)
+      end
+
+      def process_hasNamespacePermission(seqid, iprot, oprot)
+        args = read_args(iprot, HasNamespacePermission_args)
+        result = HasNamespacePermission_result.new()
+        begin
+          result.success = @handler.hasNamespacePermission(args.login, args.user, args.namespaceName, args.perm)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        end
+        write_result(result, oprot, 'hasNamespacePermission', seqid)
+      end
+
+      def process_revokeNamespacePermission(seqid, iprot, oprot)
+        args = read_args(iprot, RevokeNamespacePermission_args)
+        result = RevokeNamespacePermission_result.new()
+        begin
+          @handler.revokeNamespacePermission(args.login, args.user, args.namespaceName, args.perm)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        end
+        write_result(result, oprot, 'revokeNamespacePermission', seqid)
+      end
+
       def process_createBatchScanner(seqid, iprot, oprot)
         args = read_args(iprot, CreateBatchScanner_args)
         result = CreateBatchScanner_result.new()
@@ -2364,6 +2796,288 @@
         write_result(result, oprot, 'getFollowing', seqid)
       end
 
+      def process_systemNamespace(seqid, iprot, oprot)
+        args = read_args(iprot, SystemNamespace_args)
+        result = SystemNamespace_result.new()
+        result.success = @handler.systemNamespace()
+        write_result(result, oprot, 'systemNamespace', seqid)
+      end
+
+      def process_defaultNamespace(seqid, iprot, oprot)
+        args = read_args(iprot, DefaultNamespace_args)
+        result = DefaultNamespace_result.new()
+        result.success = @handler.defaultNamespace()
+        write_result(result, oprot, 'defaultNamespace', seqid)
+      end
+
+      def process_listNamespaces(seqid, iprot, oprot)
+        args = read_args(iprot, ListNamespaces_args)
+        result = ListNamespaces_result.new()
+        begin
+          result.success = @handler.listNamespaces(args.login)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        end
+        write_result(result, oprot, 'listNamespaces', seqid)
+      end
+
+      def process_namespaceExists(seqid, iprot, oprot)
+        args = read_args(iprot, NamespaceExists_args)
+        result = NamespaceExists_result.new()
+        begin
+          result.success = @handler.namespaceExists(args.login, args.namespaceName)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        end
+        write_result(result, oprot, 'namespaceExists', seqid)
+      end
+
+      def process_createNamespace(seqid, iprot, oprot)
+        args = read_args(iprot, CreateNamespace_args)
+        result = CreateNamespace_result.new()
+        begin
+          @handler.createNamespace(args.login, args.namespaceName)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceExistsException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'createNamespace', seqid)
+      end
+
+      def process_deleteNamespace(seqid, iprot, oprot)
+        args = read_args(iprot, DeleteNamespace_args)
+        result = DeleteNamespace_result.new()
+        begin
+          @handler.deleteNamespace(args.login, args.namespaceName)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        rescue ::Accumulo::NamespaceNotEmptyException => ouch4
+          result.ouch4 = ouch4
+        end
+        write_result(result, oprot, 'deleteNamespace', seqid)
+      end
+
+      def process_renameNamespace(seqid, iprot, oprot)
+        args = read_args(iprot, RenameNamespace_args)
+        result = RenameNamespace_result.new()
+        begin
+          @handler.renameNamespace(args.login, args.oldNamespaceName, args.newNamespaceName)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        rescue ::Accumulo::NamespaceExistsException => ouch4
+          result.ouch4 = ouch4
+        end
+        write_result(result, oprot, 'renameNamespace', seqid)
+      end
+
+      def process_setNamespaceProperty(seqid, iprot, oprot)
+        args = read_args(iprot, SetNamespaceProperty_args)
+        result = SetNamespaceProperty_result.new()
+        begin
+          @handler.setNamespaceProperty(args.login, args.namespaceName, args.property, args.value)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'setNamespaceProperty', seqid)
+      end
+
+      def process_removeNamespaceProperty(seqid, iprot, oprot)
+        args = read_args(iprot, RemoveNamespaceProperty_args)
+        result = RemoveNamespaceProperty_result.new()
+        begin
+          @handler.removeNamespaceProperty(args.login, args.namespaceName, args.property)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'removeNamespaceProperty', seqid)
+      end
+
+      def process_getNamespaceProperties(seqid, iprot, oprot)
+        args = read_args(iprot, GetNamespaceProperties_args)
+        result = GetNamespaceProperties_result.new()
+        begin
+          result.success = @handler.getNamespaceProperties(args.login, args.namespaceName)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'getNamespaceProperties', seqid)
+      end
+
+      def process_namespaceIdMap(seqid, iprot, oprot)
+        args = read_args(iprot, NamespaceIdMap_args)
+        result = NamespaceIdMap_result.new()
+        begin
+          result.success = @handler.namespaceIdMap(args.login)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        end
+        write_result(result, oprot, 'namespaceIdMap', seqid)
+      end
+
+      def process_attachNamespaceIterator(seqid, iprot, oprot)
+        args = read_args(iprot, AttachNamespaceIterator_args)
+        result = AttachNamespaceIterator_result.new()
+        begin
+          @handler.attachNamespaceIterator(args.login, args.namespaceName, args.setting, args.scopes)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'attachNamespaceIterator', seqid)
+      end
+
+      def process_removeNamespaceIterator(seqid, iprot, oprot)
+        args = read_args(iprot, RemoveNamespaceIterator_args)
+        result = RemoveNamespaceIterator_result.new()
+        begin
+          @handler.removeNamespaceIterator(args.login, args.namespaceName, args.name, args.scopes)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'removeNamespaceIterator', seqid)
+      end
+
+      def process_getNamespaceIteratorSetting(seqid, iprot, oprot)
+        args = read_args(iprot, GetNamespaceIteratorSetting_args)
+        result = GetNamespaceIteratorSetting_result.new()
+        begin
+          result.success = @handler.getNamespaceIteratorSetting(args.login, args.namespaceName, args.name, args.scope)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'getNamespaceIteratorSetting', seqid)
+      end
+
+      def process_listNamespaceIterators(seqid, iprot, oprot)
+        args = read_args(iprot, ListNamespaceIterators_args)
+        result = ListNamespaceIterators_result.new()
+        begin
+          result.success = @handler.listNamespaceIterators(args.login, args.namespaceName)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'listNamespaceIterators', seqid)
+      end
+
+      def process_checkNamespaceIteratorConflicts(seqid, iprot, oprot)
+        args = read_args(iprot, CheckNamespaceIteratorConflicts_args)
+        result = CheckNamespaceIteratorConflicts_result.new()
+        begin
+          @handler.checkNamespaceIteratorConflicts(args.login, args.namespaceName, args.setting, args.scopes)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'checkNamespaceIteratorConflicts', seqid)
+      end
+
+      def process_addNamespaceConstraint(seqid, iprot, oprot)
+        args = read_args(iprot, AddNamespaceConstraint_args)
+        result = AddNamespaceConstraint_result.new()
+        begin
+          result.success = @handler.addNamespaceConstraint(args.login, args.namespaceName, args.constraintClassName)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'addNamespaceConstraint', seqid)
+      end
+
+      def process_removeNamespaceConstraint(seqid, iprot, oprot)
+        args = read_args(iprot, RemoveNamespaceConstraint_args)
+        result = RemoveNamespaceConstraint_result.new()
+        begin
+          @handler.removeNamespaceConstraint(args.login, args.namespaceName, args.id)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'removeNamespaceConstraint', seqid)
+      end
+
+      def process_listNamespaceConstraints(seqid, iprot, oprot)
+        args = read_args(iprot, ListNamespaceConstraints_args)
+        result = ListNamespaceConstraints_result.new()
+        begin
+          result.success = @handler.listNamespaceConstraints(args.login, args.namespaceName)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'listNamespaceConstraints', seqid)
+      end
+
+      def process_testNamespaceClassLoad(seqid, iprot, oprot)
+        args = read_args(iprot, TestNamespaceClassLoad_args)
+        result = TestNamespaceClassLoad_result.new()
+        begin
+          result.success = @handler.testNamespaceClassLoad(args.login, args.namespaceName, args.className, args.asTypeName)
+        rescue ::Accumulo::AccumuloException => ouch1
+          result.ouch1 = ouch1
+        rescue ::Accumulo::AccumuloSecurityException => ouch2
+          result.ouch2 = ouch2
+        rescue ::Accumulo::NamespaceNotFoundException => ouch3
+          result.ouch3 = ouch3
+        end
+        write_result(result, oprot, 'testNamespaceClassLoad', seqid)
+      end
+
     end
 
     # HELPER FUNCTIONS AND STRUCTURES
@@ -4784,6 +5498,137 @@
       ::Thrift::Struct.generate_accessors self
     end
 
+    class GrantNamespacePermission_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      USER = 2
+      NAMESPACENAME = 3
+      PERM = 4
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        USER => {:type => ::Thrift::Types::STRING, :name => 'user'},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        PERM => {:type => ::Thrift::Types::I32, :name => 'perm', :enum_class => ::Accumulo::NamespacePermission}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+        unless @perm.nil? || ::Accumulo::NamespacePermission::VALID_VALUES.include?(@perm)
+          raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field perm!')
+        end
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class GrantNamespacePermission_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class HasNamespacePermission_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      USER = 2
+      NAMESPACENAME = 3
+      PERM = 4
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        USER => {:type => ::Thrift::Types::STRING, :name => 'user'},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        PERM => {:type => ::Thrift::Types::I32, :name => 'perm', :enum_class => ::Accumulo::NamespacePermission}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+        unless @perm.nil? || ::Accumulo::NamespacePermission::VALID_VALUES.include?(@perm)
+          raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field perm!')
+        end
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class HasNamespacePermission_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      OUCH1 = 1
+      OUCH2 = 2
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::BOOL, :name => 'success'},
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class RevokeNamespacePermission_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      USER = 2
+      NAMESPACENAME = 3
+      PERM = 4
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        USER => {:type => ::Thrift::Types::STRING, :name => 'user'},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        PERM => {:type => ::Thrift::Types::I32, :name => 'perm', :enum_class => ::Accumulo::NamespacePermission}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+        unless @perm.nil? || ::Accumulo::NamespacePermission::VALID_VALUES.include?(@perm)
+          raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field perm!')
+        end
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class RevokeNamespacePermission_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
     class CreateBatchScanner_args
       include ::Thrift::Struct, ::Thrift::Struct_Union
       LOGIN = 1
@@ -5426,6 +6271,799 @@
       ::Thrift::Struct.generate_accessors self
     end
 
+    class SystemNamespace_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+
+      FIELDS = {
+
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class SystemNamespace_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class DefaultNamespace_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+
+      FIELDS = {
+
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class DefaultNamespace_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::STRING, :name => 'success'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class ListNamespaces_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class ListNamespaces_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      OUCH1 = 1
+      OUCH2 = 2
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::LIST, :name => 'success', :element => {:type => ::Thrift::Types::STRING}},
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class NamespaceExists_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class NamespaceExists_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      OUCH1 = 1
+      OUCH2 = 2
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::BOOL, :name => 'success'},
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class CreateNamespace_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class CreateNamespace_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceExistsException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class DeleteNamespace_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class DeleteNamespace_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+      OUCH4 = 4
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException},
+        OUCH4 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch4', :class => ::Accumulo::NamespaceNotEmptyException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class RenameNamespace_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      OLDNAMESPACENAME = 2
+      NEWNAMESPACENAME = 3
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        OLDNAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'oldNamespaceName'},
+        NEWNAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'newNamespaceName'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class RenameNamespace_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+      OUCH4 = 4
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException},
+        OUCH4 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch4', :class => ::Accumulo::NamespaceExistsException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class SetNamespaceProperty_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+      PROPERTY = 3
+      VALUE = 4
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        PROPERTY => {:type => ::Thrift::Types::STRING, :name => 'property'},
+        VALUE => {:type => ::Thrift::Types::STRING, :name => 'value'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class SetNamespaceProperty_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class RemoveNamespaceProperty_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+      PROPERTY = 3
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        PROPERTY => {:type => ::Thrift::Types::STRING, :name => 'property'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class RemoveNamespaceProperty_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class GetNamespaceProperties_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class GetNamespaceProperties_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::MAP, :name => 'success', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}},
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class NamespaceIdMap_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class NamespaceIdMap_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      OUCH1 = 1
+      OUCH2 = 2
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::MAP, :name => 'success', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING}},
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class AttachNamespaceIterator_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+      SETTING = 3
+      SCOPES = 4
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        SETTING => {:type => ::Thrift::Types::STRUCT, :name => 'setting', :class => ::Accumulo::IteratorSetting},
+        SCOPES => {:type => ::Thrift::Types::SET, :name => 'scopes', :element => {:type => ::Thrift::Types::I32, :enum_class => ::Accumulo::IteratorScope}}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class AttachNamespaceIterator_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class RemoveNamespaceIterator_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+      NAME = 3
+      SCOPES = 4
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        NAME => {:type => ::Thrift::Types::STRING, :name => 'name'},
+        SCOPES => {:type => ::Thrift::Types::SET, :name => 'scopes', :element => {:type => ::Thrift::Types::I32, :enum_class => ::Accumulo::IteratorScope}}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class RemoveNamespaceIterator_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class GetNamespaceIteratorSetting_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+      NAME = 3
+      SCOPE = 4
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        NAME => {:type => ::Thrift::Types::STRING, :name => 'name'},
+        SCOPE => {:type => ::Thrift::Types::I32, :name => 'scope', :enum_class => ::Accumulo::IteratorScope}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+        unless @scope.nil? || ::Accumulo::IteratorScope::VALID_VALUES.include?(@scope)
+          raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field scope!')
+        end
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class GetNamespaceIteratorSetting_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::STRUCT, :name => 'success', :class => ::Accumulo::IteratorSetting},
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class ListNamespaceIterators_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class ListNamespaceIterators_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::MAP, :name => 'success', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::SET, :element => {:type => ::Thrift::Types::I32, :enum_class => ::Accumulo::IteratorScope}}},
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class CheckNamespaceIteratorConflicts_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+      SETTING = 3
+      SCOPES = 4
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        SETTING => {:type => ::Thrift::Types::STRUCT, :name => 'setting', :class => ::Accumulo::IteratorSetting},
+        SCOPES => {:type => ::Thrift::Types::SET, :name => 'scopes', :element => {:type => ::Thrift::Types::I32, :enum_class => ::Accumulo::IteratorScope}}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class CheckNamespaceIteratorConflicts_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class AddNamespaceConstraint_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+      CONSTRAINTCLASSNAME = 3
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        CONSTRAINTCLASSNAME => {:type => ::Thrift::Types::STRING, :name => 'constraintClassName'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class AddNamespaceConstraint_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::I32, :name => 'success'},
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class RemoveNamespaceConstraint_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+      ID = 3
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        ID => {:type => ::Thrift::Types::I32, :name => 'id'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class RemoveNamespaceConstraint_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class ListNamespaceConstraints_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class ListNamespaceConstraints_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::MAP, :name => 'success', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::I32}},
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class TestNamespaceClassLoad_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      LOGIN = 1
+      NAMESPACENAME = 2
+      CLASSNAME = 3
+      ASTYPENAME = 4
+
+      FIELDS = {
+        LOGIN => {:type => ::Thrift::Types::STRING, :name => 'login', :binary => true},
+        NAMESPACENAME => {:type => ::Thrift::Types::STRING, :name => 'namespaceName'},
+        CLASSNAME => {:type => ::Thrift::Types::STRING, :name => 'className'},
+        ASTYPENAME => {:type => ::Thrift::Types::STRING, :name => 'asTypeName'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class TestNamespaceClassLoad_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      OUCH1 = 1
+      OUCH2 = 2
+      OUCH3 = 3
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::BOOL, :name => 'success'},
+        OUCH1 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch1', :class => ::Accumulo::AccumuloException},
+        OUCH2 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch2', :class => ::Accumulo::AccumuloSecurityException},
+        OUCH3 => {:type => ::Thrift::Types::STRUCT, :name => 'ouch3', :class => ::Accumulo::NamespaceNotFoundException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
   end
 
 end
diff --git a/src/main/ruby/proxy_constants.rb b/src/main/ruby/proxy_constants.rb
index 98a589e..baaf9af 100644
--- a/src/main/ruby/proxy_constants.rb
+++ b/src/main/ruby/proxy_constants.rb
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Autogenerated by Thrift Compiler (0.9.1)
+# Autogenerated by Thrift Compiler (0.9.3)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
diff --git a/src/main/ruby/proxy_types.rb b/src/main/ruby/proxy_types.rb
index 522c80c..ddf8a18 100644
--- a/src/main/ruby/proxy_types.rb
+++ b/src/main/ruby/proxy_types.rb
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Autogenerated by Thrift Compiler (0.9.1)
+# Autogenerated by Thrift Compiler (0.9.3)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
@@ -60,6 +60,20 @@
     VALID_VALUES = Set.new([GRANT, CREATE_TABLE, DROP_TABLE, ALTER_TABLE, CREATE_USER, DROP_USER, ALTER_USER, SYSTEM, CREATE_NAMESPACE, DROP_NAMESPACE, ALTER_NAMESPACE, OBTAIN_DELEGATION_TOKEN]).freeze
   end
 
+  module NamespacePermission
+    READ = 0
+    WRITE = 1
+    ALTER_NAMESPACE = 2
+    GRANT = 3
+    ALTER_TABLE = 4
+    CREATE_TABLE = 5
+    DROP_TABLE = 6
+    BULK_IMPORT = 7
+    DROP_NAMESPACE = 8
+    VALUE_MAP = {0 => "READ", 1 => "WRITE", 2 => "ALTER_NAMESPACE", 3 => "GRANT", 4 => "ALTER_TABLE", 5 => "CREATE_TABLE", 6 => "DROP_TABLE", 7 => "BULK_IMPORT", 8 => "DROP_NAMESPACE"}
+    VALID_VALUES = Set.new([READ, WRITE, ALTER_NAMESPACE, GRANT, ALTER_TABLE, CREATE_TABLE, DROP_TABLE, BULK_IMPORT, DROP_NAMESPACE]).freeze
+  end
+
   module ScanType
     SINGLE = 0
     BATCH = 1
@@ -779,4 +793,73 @@
     ::Thrift::Struct.generate_accessors self
   end
 
+  class NamespaceExistsException < ::Thrift::Exception
+    include ::Thrift::Struct, ::Thrift::Struct_Union
+    def initialize(message=nil)
+      super()
+      self.msg = message
+    end
+
+    def message; msg end
+
+    MSG = 1
+
+    FIELDS = {
+      MSG => {:type => ::Thrift::Types::STRING, :name => 'msg'}
+    }
+
+    def struct_fields; FIELDS; end
+
+    def validate
+    end
+
+    ::Thrift::Struct.generate_accessors self
+  end
+
+  class NamespaceNotFoundException < ::Thrift::Exception
+    include ::Thrift::Struct, ::Thrift::Struct_Union
+    def initialize(message=nil)
+      super()
+      self.msg = message
+    end
+
+    def message; msg end
+
+    MSG = 1
+
+    FIELDS = {
+      MSG => {:type => ::Thrift::Types::STRING, :name => 'msg'}
+    }
+
+    def struct_fields; FIELDS; end
+
+    def validate
+    end
+
+    ::Thrift::Struct.generate_accessors self
+  end
+
+  class NamespaceNotEmptyException < ::Thrift::Exception
+    include ::Thrift::Struct, ::Thrift::Struct_Union
+    def initialize(message=nil)
+      super()
+      self.msg = message
+    end
+
+    def message; msg end
+
+    MSG = 1
+
+    FIELDS = {
+      MSG => {:type => ::Thrift::Types::STRING, :name => 'msg'}
+    }
+
+    def struct_fields; FIELDS; end
+
+    def validate
+    end
+
+    ::Thrift::Struct.generate_accessors self
+  end
+
 end
diff --git a/src/main/thrift/proxy.thrift b/src/main/thrift/proxy.thrift
index 00427c0..e15990c 100644
--- a/src/main/thrift/proxy.thrift
+++ b/src/main/thrift/proxy.thrift
@@ -137,6 +137,18 @@
   OBTAIN_DELEGATION_TOKEN = 11,
 }
 
+enum NamespacePermission {
+  READ = 0,
+  WRITE = 1,
+  ALTER_NAMESPACE = 2,
+  GRANT = 3,
+  ALTER_TABLE = 4,
+  CREATE_TABLE = 5,
+  DROP_TABLE = 6,
+  BULK_IMPORT = 7,
+  DROP_NAMESPACE = 8
+}
+
 enum ScanType {
     SINGLE,
     BATCH
@@ -301,6 +313,18 @@
   1:string msg
 }
 
+exception NamespaceExistsException {
+  1:string msg
+}
+
+exception NamespaceNotFoundException {
+  1:string msg
+}
+
+exception NamespaceNotEmptyException {
+  1:string msg
+}
+
 service AccumuloProxy
 {
   // get an authentication token
@@ -394,6 +418,12 @@
   set<string> listLocalUsers (1:binary login)                                                        throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:TableNotFoundException ouch3);
   void revokeSystemPermission (1:binary login, 2:string user, 3:SystemPermission perm)               throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2);
   void revokeTablePermission (1:binary login, 2:string user, 3:string table, 4:TablePermission perm) throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:TableNotFoundException ouch3);
+  void grantNamespacePermission (1:binary login, 2:string user, 3:string namespaceName,
+                                 4:NamespacePermission perm)                                         throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2);
+  bool hasNamespacePermission (1:binary login, 2:string user, 3:string namespaceName,
+                               4:NamespacePermission perm)                                           throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2);
+  void revokeNamespacePermission (1:binary login, 2:string user, 3:string namespaceName,
+                                  4:NamespacePermission perm)                                        throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2);
 
   // scanning
   string createBatchScanner(1:binary login, 2:string tableName, 3:BatchScanOptions options)          throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:TableNotFoundException ouch3);
@@ -431,4 +461,33 @@
   // utilities
   Range getRowRange(1:binary row);
   Key getFollowing(1:Key key, 2:PartialKey part);
-}
\ No newline at end of file
+
+  // namespace operations, since 1.8.0
+  string systemNamespace();
+  string defaultNamespace();
+  list<string> listNamespaces(1:binary login)                                                      throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2);
+  bool namespaceExists(1:binary login, 2:string namespaceName)                                     throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2);
+  void createNamespace(1:binary login, 2:string namespaceName)                                     throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceExistsException ouch3);
+  void deleteNamespace(1:binary login, 2:string namespaceName)                                     throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3, 4:NamespaceNotEmptyException ouch4);
+  void renameNamespace(1:binary login, 2:string oldNamespaceName, 3:string newNamespaceName)       throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3, 4:NamespaceExistsException ouch4);
+  void setNamespaceProperty(1:binary login, 2:string namespaceName, 3:string property,
+                            4:string value)                                                        throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  void removeNamespaceProperty(1:binary login, 2:string namespaceName, 3:string property)          throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  map<string,string> getNamespaceProperties(1:binary login, 2:string namespaceName)                throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  map<string,string> namespaceIdMap(1:binary login)                                                throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2);
+  void attachNamespaceIterator(1:binary login, 2:string namespaceName, 3:IteratorSetting setting,
+                               4:set<IteratorScope> scopes)                                        throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  void removeNamespaceIterator(1:binary login, 2:string namespaceName, 3:string name,
+                               4:set<IteratorScope> scopes)                                        throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  IteratorSetting getNamespaceIteratorSetting(1:binary login, 2:string namespaceName,
+                                              3:string name, 4:IteratorScope scope)                throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  map<string,set<IteratorScope>> listNamespaceIterators(1:binary login, 2:string namespaceName)    throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  void checkNamespaceIteratorConflicts(1:binary login, 2:string namespaceName,
+                                       3:IteratorSetting setting, 4:set<IteratorScope> scopes)     throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  i32 addNamespaceConstraint(1:binary login, 2:string namespaceName,
+                             3:string constraintClassName)                                         throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  void removeNamespaceConstraint(1:binary login, 2:string namespaceName, 3:i32 id)                 throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  map<string,i32> listNamespaceConstraints(1:binary login, 2:string namespaceName)                 throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+  bool testNamespaceClassLoad(1:binary login, 2:string namespaceName, 3:string className,
+                              4:string asTypeName)                                                 throws (1:AccumuloException ouch1, 2:AccumuloSecurityException ouch2, 3:NamespaceNotFoundException ouch3);
+}
