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 a055b48..09c2d9c 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 {
 
@@ -84,6 +87,30 @@
 };
 const std::map<int, const char*> _SystemPermission_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(8, _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
@@ -190,11 +217,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;
@@ -267,6 +318,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);
@@ -305,11 +357,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;
@@ -390,6 +501,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);
@@ -436,11 +548,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;
@@ -463,14 +617,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();
           }
@@ -501,15 +655,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();
   }
@@ -531,11 +686,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;
@@ -584,6 +769,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);
@@ -606,11 +792,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;
@@ -633,14 +849,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();
           }
@@ -671,15 +887,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();
   }
@@ -701,11 +918,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;
@@ -770,6 +1025,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);
@@ -802,11 +1058,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;
@@ -855,6 +1148,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);
@@ -878,11 +1172,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;
@@ -929,17 +1261,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();
           }
@@ -962,6 +1294,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);
@@ -979,11 +1312,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();
   }
@@ -1003,11 +1336,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;
@@ -1030,15 +1416,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();
           }
@@ -1059,14 +1445,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();
           }
@@ -1079,14 +1465,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();
           }
@@ -1117,16 +1503,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();
     }
@@ -1141,10 +1528,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();
     }
@@ -1154,10 +1541,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();
     }
@@ -1183,11 +1570,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;
@@ -1210,15 +1653,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();
           }
@@ -1231,14 +1674,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();
           }
@@ -1251,14 +1694,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();
           }
@@ -1271,14 +1714,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();
           }
@@ -1309,16 +1752,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();
     }
@@ -1328,10 +1772,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();
     }
@@ -1341,10 +1785,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();
     }
@@ -1354,10 +1798,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();
     }
@@ -1383,11 +1827,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;
@@ -1436,6 +1919,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);
@@ -1458,11 +1942,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;
@@ -1519,6 +2037,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);
@@ -1546,11 +2065,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;
@@ -1607,6 +2163,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);
@@ -1634,11 +2191,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;
@@ -1685,14 +2286,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();
           }
@@ -1715,6 +2316,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);
@@ -1735,10 +2337,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();
     }
@@ -1758,11 +2360,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;
@@ -1785,14 +2423,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();
           }
@@ -1805,14 +2443,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();
           }
@@ -1835,15 +2473,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();
   }
@@ -1852,10 +2491,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();
   }
@@ -1873,11 +2512,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;
@@ -1924,15 +2610,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();
           }
@@ -1943,9 +2629,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);
@@ -1965,6 +2651,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) {
@@ -1986,10 +2673,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();
     }
@@ -2015,11 +2702,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;
@@ -2080,9 +2842,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);
@@ -2090,9 +2852,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);
@@ -2110,14 +2872,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();
           }
@@ -2130,14 +2892,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();
           }
@@ -2150,14 +2912,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();
           }
@@ -2180,6 +2942,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);
@@ -2217,10 +2980,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();
   }
@@ -2229,10 +2992,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();
   }
@@ -2241,10 +3004,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();
   }
@@ -2271,11 +3034,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;
@@ -2314,14 +3166,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();
           }
@@ -2340,9 +3192,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);
@@ -2350,9 +3202,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);
@@ -2386,14 +3238,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();
           }
@@ -2416,6 +3268,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);
@@ -2429,10 +3282,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();
   }
@@ -2465,10 +3318,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();
   }
@@ -2494,11 +3347,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;
@@ -2551,9 +3471,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);
@@ -2573,6 +3493,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);
@@ -2611,11 +3532,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;
@@ -2646,17 +3606,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();
           }
@@ -2679,6 +3639,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);
@@ -2688,11 +3649,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();
   }
@@ -2710,11 +3671,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;
@@ -2755,6 +3742,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);
@@ -2772,11 +3760,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;
@@ -2817,6 +3839,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);
@@ -2834,11 +3857,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;
@@ -2879,6 +3936,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);
@@ -2896,11 +3954,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;
@@ -2941,6 +4033,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);
@@ -2958,11 +4051,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;
@@ -3003,6 +4130,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);
@@ -3020,11 +4148,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;
@@ -3065,6 +4227,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);
@@ -3082,11 +4245,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;
@@ -3127,6 +4324,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);
@@ -3144,11 +4342,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;
@@ -3189,6 +4421,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);
@@ -3206,4 +4439,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 569de88..e5daf2e 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>
@@ -74,6 +76,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,
@@ -159,26 +177,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;
@@ -187,26 +265,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
   {
@@ -233,31 +300,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;
@@ -267,33 +339,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
   {
@@ -328,39 +384,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
   {
@@ -379,39 +436,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
   {
@@ -430,39 +488,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
   {
@@ -481,29 +540,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;
@@ -511,21 +575,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
   {
@@ -548,40 +604,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
   {
@@ -602,29 +658,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;
@@ -632,21 +693,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
   {
@@ -669,30 +722,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;
@@ -701,30 +759,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
   {
@@ -759,30 +802,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;
@@ -791,30 +839,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
   {
@@ -849,39 +882,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
   {
@@ -900,45 +934,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
   {
@@ -959,45 +992,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
   {
@@ -1018,29 +1050,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;
@@ -1048,24 +1085,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
   {
@@ -1094,39 +1120,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
   {
@@ -1145,30 +1172,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;
@@ -1177,30 +1209,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
   {
@@ -1235,36 +1252,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;
@@ -1279,49 +1301,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
   {
@@ -1358,35 +1358,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;
@@ -1400,45 +1405,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
   {
@@ -1473,30 +1458,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;
@@ -1505,26 +1495,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
   {
@@ -1551,39 +1530,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
   {
@@ -1602,33 +1582,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
   {
@@ -1645,33 +1628,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
   {
@@ -1688,33 +1676,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
   {
@@ -1731,33 +1724,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
   {
@@ -1774,33 +1772,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
   {
@@ -1817,33 +1820,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
   {
@@ -1860,33 +1868,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
   {
@@ -1903,33 +1916,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
   {
@@ -1946,10 +1964,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 929b83a..6f4b549 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 9444f71..87a977d 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
 #
@@ -114,6 +114,41 @@
     "SYSTEM": 7,
   }
 
+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
@@ -303,27 +338,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:
@@ -363,6 +398,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()]
@@ -414,32 +458,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:
@@ -483,6 +527,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()]
@@ -525,14 +579,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:
@@ -563,6 +617,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()]
@@ -608,7 +668,7 @@
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.STRING:
-          self.value = iprot.readString();
+          self.value = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -636,6 +696,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()]
@@ -686,7 +752,7 @@
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.BOOL:
-          self.more = iprot.readBool();
+          self.more = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -717,6 +783,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()]
@@ -768,7 +840,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:
@@ -779,7 +851,7 @@
           iprot.skip(ftype)
       elif fid == 4:
         if ftype == TType.BOOL:
-          self.stopInclusive = iprot.readBool();
+          self.stopInclusive = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -815,6 +887,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()]
@@ -854,12 +934,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:
@@ -887,6 +967,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()]
@@ -932,17 +1018,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:
@@ -950,8 +1036,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:
@@ -993,6 +1079,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()]
@@ -1044,7 +1138,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:
@@ -1079,7 +1173,7 @@
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.I32:
-          self.bufferSize = iprot.readI32();
+          self.bufferSize = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -1128,6 +1222,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()]
@@ -1179,7 +1282,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:
@@ -1219,7 +1322,7 @@
           iprot.skip(ftype)
       elif fid == 5:
         if ftype == TType.I32:
-          self.threads = iprot.readI32();
+          self.threads = iprot.readI32()
         else:
           iprot.skip(ftype)
       else:
@@ -1271,6 +1374,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()]
@@ -1316,7 +1428,7 @@
           iprot.skip(ftype)
       elif fid == 2:
         if ftype == TType.BOOL:
-          self.hasNext = iprot.readBool();
+          self.hasNext = iprot.readBool()
         else:
           iprot.skip(ftype)
       else:
@@ -1344,6 +1456,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()]
@@ -1386,17 +1504,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:
@@ -1428,6 +1546,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()]
@@ -1470,17 +1595,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:
@@ -1512,6 +1637,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()]
@@ -1563,12 +1695,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:
@@ -1618,6 +1750,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()]
@@ -1709,6 +1849,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()]
@@ -1757,17 +1903,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:
@@ -1775,14 +1921,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:
@@ -1825,6 +1971,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()]
@@ -1891,37 +2046,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:
@@ -1957,7 +2112,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:
@@ -2032,6 +2187,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()]
@@ -2101,7 +2271,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:
@@ -2109,39 +2279,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:
@@ -2218,6 +2388,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()]
@@ -2266,27 +2450,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:
@@ -2326,6 +2510,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()]
@@ -2365,7 +2558,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.className = iprot.readString();
+          self.className = iprot.readString()
         else:
           iprot.skip(ftype)
       elif fid == 2:
@@ -2373,8 +2566,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:
@@ -2408,6 +2601,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()]
@@ -2444,7 +2643,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2471,6 +2670,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()]
@@ -2507,7 +2711,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2534,6 +2738,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()]
@@ -2570,7 +2779,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2597,6 +2806,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()]
@@ -2633,7 +2847,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2660,6 +2874,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()]
@@ -2696,7 +2915,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2723,6 +2942,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()]
@@ -2759,7 +2983,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2786,6 +3010,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()]
@@ -2822,7 +3051,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2849,6 +3078,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()]
@@ -2885,7 +3119,7 @@
         break
       if fid == 1:
         if ftype == TType.STRING:
-          self.msg = iprot.readString();
+          self.msg = iprot.readString()
         else:
           iprot.skip(ftype)
       else:
@@ -2912,6 +3146,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 57306d1..e542df6 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
 #
@@ -56,6 +56,20 @@
     VALID_VALUES = Set.new([GRANT, CREATE_TABLE, DROP_TABLE, ALTER_TABLE, CREATE_USER, DROP_USER, ALTER_USER, SYSTEM]).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
@@ -775,4 +789,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 25510d1..3814c44 100644
--- a/src/main/thrift/proxy.thrift
+++ b/src/main/thrift/proxy.thrift
@@ -133,6 +133,18 @@
   SYSTEM = 7,
 }
 
+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
@@ -297,6 +309,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
@@ -390,6 +414,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);
@@ -427,4 +457,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);
+}
