diff --git a/README b/README
deleted file mode 100644
index 1f44a9c..0000000
--- a/README
+++ /dev/null
@@ -1,62 +0,0 @@
-Title: Apache Accumulo Proxy
-Notice:    Licensed to the Apache Software Foundation (ASF) under one
-           or more contributor license agreements.  See the NOTICE file
-           distributed with this work for additional information
-           regarding copyright ownership.  The ASF licenses this file
-           to you under the Apache License, Version 2.0 (the
-           "License"); you may not use this file except in compliance
-           with the License.  You may obtain a copy of the License at
-           .
-             http://www.apache.org/licenses/LICENSE-2.0
-           .
-           Unless required by applicable law or agreed to in writing,
-           software distributed under the License is distributed on an
-           "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-           KIND, either express or implied.  See the License for the
-           specific language governing permissions and limitations
-           under the License.
-
-This module provides proxy server for Apache Accumulo. It enables using languages 
-other than Java to interact with the database.
-
-1. Building
-
-The proxy server is built by the Accumulo build process. Read ../README
-for more information.
-
-2. Installation
-
-The proxy server is installed during the Accumulo installation process. Read ../README
-for more information.
-
-3. Configuration
-
-Please note the proxy server only functions correctly when connected to an 
-Accumulo 1.5 instance, or when run standalone in the Mock configuration.
-
- - Edit the proxy.properties file.
-    - Change the useMockInstance value to 'true' if you wish to use an in-memory Mock instance.
-    - Change the useMiniAccumulo value to 'true' if you wish to use a Mini Accumulo Cluster.
-    - When using a "real" Accumulo instance:
-        - Ensure useMockInstance and useMiniAccumulo are both set to 'false'
-        - Set the instance name
-        - Set the list of ZooKeepers
-
-4. Execution
-
-Run the following command.
-
- ${ACCUMULO_HOME}/bin/accumulo proxy -p ${ACCUMULO_HOME}/proxy/proxy.properties
-
-5. Clients
-
-You need the language-specific library for Thrift installed to be able to use said Thrift client 
-code in that language. In other words, you need to install the Python Thrift library to use the Python 
-example. Typically, your operating system's package manager will be able to automatically install
-these for you in an expected location such as /usr/lib/python/site-packages/thrift.
-
-An example Java client is incuded with this distribution in the class TestProxyClient. Also the 
-unit tests included show how to use the proxy. Normal Accumulo APIs are emulated wherever possible.
-
-Additional client examples can be found in the examples directory. These clients are tested and 
-functional; however, the setup for each language is beyond the scope of this document currently.
diff --git a/examples/python/README b/examples/python/README
deleted file mode 100644
index 093f3cf..0000000
--- a/examples/python/README
+++ /dev/null
@@ -1,24 +0,0 @@
-Title: Apache Accumulo Python Example
-Notice:    Licensed to the Apache Software Foundation (ASF) under one
-           or more contributor license agreements.  See the NOTICE file
-           distributed with this work for additional information
-           regarding copyright ownership.  The ASF licenses this file
-           to you under the Apache License, Version 2.0 (the
-           "License"); you may not use this file except in compliance
-           with the License.  You may obtain a copy of the License at
-           .
-             http://www.apache.org/licenses/LICENSE-2.0
-           .
-           Unless required by applicable law or agreed to in writing,
-           software distributed under the License is distributed on an
-           "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-           KIND, either express or implied.  See the License for the
-           specific language governing permissions and limitations
-           under the License.
-
-This is an example python client for the accumulo proxy. After launching the proxy server, You should be able to run it by typing:
-
-
-PYTHONPATH=path/to/generated/api:path/to/thrift/libs python TestClient.py
-
-As a warning, this script will create a table in your accumulo instance and add a few cells to it.
diff --git a/examples/python/TestClient.py b/examples/python/TestClient.py
deleted file mode 100644
index f104387..0000000
--- a/examples/python/TestClient.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#! /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.
-
-import sys
-
-from thrift import Thrift
-from thrift.transport import TSocket
-from thrift.transport import TTransport
-from thrift.protocol import TCompactProtocol
-
-from accumulo import AccumuloProxy
-from accumulo.ttypes import *
-
-transport = TSocket.TSocket('localhost', 42424)
-transport = TTransport.TFramedTransport(transport)
-protocol = TCompactProtocol.TCompactProtocol(transport)
-client = AccumuloProxy.Client(protocol)
-transport.open()
-
-login = client.login('root', {'password':'secret'})
-
-print client.listTables(login)
-
-testtable = "pythontest"
-if not client.tableExists(login, testtable):
-    client.createTable(login, testtable, True, TimeType.MILLIS)
-
-row1 = {'a':[ColumnUpdate('a','a',value='value1'), ColumnUpdate('b','b',value='value2')]}
-client.updateAndFlush(login, testtable, row1)
-
-cookie = client.createScanner(login, testtable, None)
-for entry in client.nextK(cookie, 10).results:
-   print entry
diff --git a/examples/python/TestNamespace.py b/examples/python/TestNamespace.py
deleted file mode 100644
index e7d2377..0000000
--- a/examples/python/TestNamespace.py
+++ /dev/null
@@ -1,172 +0,0 @@
-#! /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/examples/ruby/README b/examples/ruby/README
deleted file mode 100644
index 1b616b0..0000000
--- a/examples/ruby/README
+++ /dev/null
@@ -1,26 +0,0 @@
-Title: Apache Accumulo Ruby Example
-Notice:    Licensed to the Apache Software Foundation (ASF) under one
-           or more contributor license agreements.  See the NOTICE file
-           distributed with this work for additional information
-           regarding copyright ownership.  The ASF licenses this file
-           to you under the Apache License, Version 2.0 (the
-           "License"); you may not use this file except in compliance
-           with the License.  You may obtain a copy of the License at
-           .
-             http://www.apache.org/licenses/LICENSE-2.0
-           .
-           Unless required by applicable law or agreed to in writing,
-           software distributed under the License is distributed on an
-           "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-           KIND, either express or implied.  See the License for the
-           specific language governing permissions and limitations
-           under the License.
-
-This directory contains the compiled thrift Accumulo proxy API and an example client for ruby.
-
-To run this script, type the following:
-ruby -I . test_client.rb <host of server>
-
-(the -I option is needed for ruby 1.9.x)
-
-Warning: the script as it is will attempt to connect to your accumulo instance, create a table, and add some rows to it.
diff --git a/examples/ruby/test_client.rb b/examples/ruby/test_client.rb
deleted file mode 100644
index 6310a2f..0000000
--- a/examples/ruby/test_client.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-require 'rubygems'
-require 'thrift'
-require 'accumulo_proxy'
-
-server = ARGV[0] || 'localhost'
-
-socket = Thrift::Socket.new(server, 42424, 9001)
-transport = Thrift::FramedTransport.new(socket)
-proto = Thrift::CompactProtocol.new(transport)
-proxy = Accumulo::AccumuloProxy::Client.new(proto)
-
-# open up the connect
-transport.open()
-
-# Test if the server is up
-login = proxy.login('root', {'password' => 'secret'})
-
-# print out a table list
-puts "List of tables: #{proxy.listTables(login).inspect}"
-
-testtable = "rubytest"
-proxy.createTable(login, testtable, true, Accumulo::TimeType::MILLIS) unless proxy.tableExists(login,testtable) 
-
-update1 = Accumulo::ColumnUpdate.new({'colFamily' => "cf1", 'colQualifier' => "cq1", 'value'=> "a"})
-update2 = Accumulo::ColumnUpdate.new({'colFamily' => "cf2", 'colQualifier' => "cq2", 'value'=> "b"})
-proxy.updateAndFlush(login,testtable,{'row1' => [update1,update2]})
-
-cookie = proxy.createScanner(login,testtable,nil)
-result = proxy.nextK(cookie,10)
-result.results.each{ |keyvalue| puts "Key: #{keyvalue.key.inspect} Value: #{keyvalue.value}" }
-
-transport.close()
diff --git a/pom.xml b/pom.xml
index 93768b1..2e441bb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.apache.accumulo</groupId>
     <artifactId>accumulo-project</artifactId>
-    <version>1.9.0-SNAPSHOT</version>
+    <version>2.0.0-SNAPSHOT</version>
   </parent>
   <artifactId>accumulo-proxy</artifactId>
   <name>Apache Accumulo Proxy</name>
@@ -40,12 +40,12 @@
       <artifactId>guava</artifactId>
     </dependency>
     <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
+      <groupId>commons-configuration</groupId>
+      <artifactId>commons-configuration</artifactId>
     </dependency>
     <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.accumulo</groupId>
@@ -60,6 +60,10 @@
       <artifactId>accumulo-server-base</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.apache.accumulo</groupId>
+      <artifactId>accumulo-start</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-client</artifactId>
     </dependency>
@@ -77,11 +81,6 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.accumulo</groupId>
-      <artifactId>accumulo-examples-simple</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>org.easymock</groupId>
       <artifactId>easymock</artifactId>
       <scope>test</scope>
diff --git a/proxy.properties b/proxy.properties
index 6a38c43..e6f3d2d 100644
--- a/proxy.properties
+++ b/proxy.properties
@@ -13,12 +13,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# Accumulo instance name
+instance=test
+# List of Zookeepers
+zookeepers=localhost:2181
+# Port to run proxy on
+port=42424
+# Set to true if you wish to an in-memory Mock instance
 useMockInstance=false
+# Set to true if you wish to use an Mini Accumulo Cluster
 useMiniAccumulo=false
 protocolFactory=org.apache.thrift.protocol.TCompactProtocol$Factory
 tokenClass=org.apache.accumulo.core.client.security.tokens.PasswordToken
-port=42424
 maxFrameSize=16M
-
-instance=test
-zookeepers=localhost:2181
diff --git a/src/main/cpp/AccumuloProxy.cpp b/src/main/cpp/AccumuloProxy.cpp
index d0add35..dbd45dd 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/cpp/AccumuloProxy.h b/src/main/cpp/AccumuloProxy.h
index 429cf55..7dd477b 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/cpp/proxy_constants.cpp b/src/main/cpp/proxy_constants.cpp
index d177867..07fb1b8 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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 c2d6fd6..436a732 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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 87ef7ac..f4f17fc 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
diff --git a/src/main/cpp/proxy_types.h b/src/main/cpp/proxy_types.h
index 6c02404..f393d62 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -27,6 +27,7 @@
 
 #include <thrift/Thrift.h>
 #include <thrift/TApplicationException.h>
+#include <thrift/TBase.h>
 #include <thrift/protocol/TProtocol.h>
 #include <thrift/transport/TTransport.h>
 
@@ -252,7 +253,7 @@
   bool timestamp :1;
 } _Key__isset;
 
-class Key {
+class Key : public virtual ::apache::thrift::TBase {
  public:
 
   Key(const Key&);
@@ -325,7 +326,7 @@
   bool deleteCell :1;
 } _ColumnUpdate__isset;
 
-class ColumnUpdate {
+class ColumnUpdate : public virtual ::apache::thrift::TBase {
  public:
 
   ColumnUpdate(const ColumnUpdate&);
@@ -405,7 +406,7 @@
   bool usage :1;
 } _DiskUsage__isset;
 
-class DiskUsage {
+class DiskUsage : public virtual ::apache::thrift::TBase {
  public:
 
   DiskUsage(const DiskUsage&);
@@ -457,7 +458,7 @@
   bool value :1;
 } _KeyValue__isset;
 
-class KeyValue {
+class KeyValue : public virtual ::apache::thrift::TBase {
  public:
 
   KeyValue(const KeyValue&);
@@ -509,7 +510,7 @@
   bool more :1;
 } _ScanResult__isset;
 
-class ScanResult {
+class ScanResult : public virtual ::apache::thrift::TBase {
  public:
 
   ScanResult(const ScanResult&);
@@ -563,7 +564,7 @@
   bool stopInclusive :1;
 } _Range__isset;
 
-class Range {
+class Range : public virtual ::apache::thrift::TBase {
  public:
 
   Range(const Range&);
@@ -625,7 +626,7 @@
   bool colQualifier :1;
 } _ScanColumn__isset;
 
-class ScanColumn {
+class ScanColumn : public virtual ::apache::thrift::TBase {
  public:
 
   ScanColumn(const ScanColumn&);
@@ -681,7 +682,7 @@
   bool properties :1;
 } _IteratorSetting__isset;
 
-class IteratorSetting {
+class IteratorSetting : public virtual ::apache::thrift::TBase {
  public:
 
   IteratorSetting(const IteratorSetting&);
@@ -746,7 +747,7 @@
   bool bufferSize :1;
 } _ScanOptions__isset;
 
-class ScanOptions {
+class ScanOptions : public virtual ::apache::thrift::TBase {
  public:
 
   ScanOptions(const ScanOptions&);
@@ -826,7 +827,7 @@
   bool threads :1;
 } _BatchScanOptions__isset;
 
-class BatchScanOptions {
+class BatchScanOptions : public virtual ::apache::thrift::TBase {
  public:
 
   BatchScanOptions(const BatchScanOptions&);
@@ -903,7 +904,7 @@
   bool hasNext :1;
 } _KeyValueAndPeek__isset;
 
-class KeyValueAndPeek {
+class KeyValueAndPeek : public virtual ::apache::thrift::TBase {
  public:
 
   KeyValueAndPeek(const KeyValueAndPeek&);
@@ -956,7 +957,7 @@
   bool prevEndRow :1;
 } _KeyExtent__isset;
 
-class KeyExtent {
+class KeyExtent : public virtual ::apache::thrift::TBase {
  public:
 
   KeyExtent(const KeyExtent&);
@@ -1014,7 +1015,7 @@
   bool colVisibility :1;
 } _Column__isset;
 
-class Column {
+class Column : public virtual ::apache::thrift::TBase {
  public:
 
   Column(const Column&);
@@ -1073,7 +1074,7 @@
   bool iterators :1;
 } _Condition__isset;
 
-class Condition {
+class Condition : public virtual ::apache::thrift::TBase {
  public:
 
   Condition(const Condition&);
@@ -1141,7 +1142,7 @@
   bool updates :1;
 } _ConditionalUpdates__isset;
 
-class ConditionalUpdates {
+class ConditionalUpdates : public virtual ::apache::thrift::TBase {
  public:
 
   ConditionalUpdates(const ConditionalUpdates&);
@@ -1196,7 +1197,7 @@
   bool durability :1;
 } _ConditionalWriterOptions__isset;
 
-class ConditionalWriterOptions {
+class ConditionalWriterOptions : public virtual ::apache::thrift::TBase {
  public:
 
   ConditionalWriterOptions(const ConditionalWriterOptions&);
@@ -1282,7 +1283,7 @@
   bool authorizations :1;
 } _ActiveScan__isset;
 
-class ActiveScan {
+class ActiveScan : public virtual ::apache::thrift::TBase {
  public:
 
   ActiveScan(const ActiveScan&);
@@ -1387,7 +1388,7 @@
   bool iterators :1;
 } _ActiveCompaction__isset;
 
-class ActiveCompaction {
+class ActiveCompaction : public virtual ::apache::thrift::TBase {
  public:
 
   ActiveCompaction(const ActiveCompaction&);
@@ -1482,7 +1483,7 @@
   bool durability :1;
 } _WriterOptions__isset;
 
-class WriterOptions {
+class WriterOptions : public virtual ::apache::thrift::TBase {
  public:
 
   WriterOptions(const WriterOptions&);
@@ -1551,7 +1552,7 @@
   bool options :1;
 } _CompactionStrategyConfig__isset;
 
-class CompactionStrategyConfig {
+class CompactionStrategyConfig : public virtual ::apache::thrift::TBase {
  public:
 
   CompactionStrategyConfig(const CompactionStrategyConfig&);
diff --git a/src/main/java/org/apache/accumulo/proxy/Proxy.java b/src/main/java/org/apache/accumulo/proxy/Proxy.java
index 457ea5a..e89f8e9 100644
--- a/src/main/java/org/apache/accumulo/proxy/Proxy.java
+++ b/src/main/java/org/apache/accumulo/proxy/Proxy.java
@@ -28,7 +28,7 @@
 import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
 import org.apache.accumulo.core.client.impl.ClientContext;
 import org.apache.accumulo.core.client.security.tokens.KerberosToken;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.ConfigurationTypeHelper;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.rpc.SslConnectionParams;
 import org.apache.accumulo.core.util.HostAndPort;
@@ -103,7 +103,7 @@
   }
 
   public static class Opts extends Help {
-    @Parameter(names = "-p", required = true, description = "properties file name", converter = PropertiesConverter.class)
+    @Parameter(names = "-p", description = "properties file name", converter = PropertiesConverter.class)
     Properties prop;
   }
 
@@ -113,14 +113,38 @@
   }
 
   @Override
+  public UsageGroup usageGroup() {
+    return UsageGroup.PROCESS;
+  }
+
+  @Override
+  public String description() {
+    return "Starts Accumulo proxy";
+  }
+
+  @Override
   public void execute(final String[] args) throws Exception {
     Opts opts = new Opts();
     opts.parseArgs(Proxy.class.getName(), args);
 
-    boolean useMini = Boolean.parseBoolean(opts.prop.getProperty(USE_MINI_ACCUMULO_KEY, USE_MINI_ACCUMULO_DEFAULT));
-    boolean useMock = Boolean.parseBoolean(opts.prop.getProperty(USE_MOCK_INSTANCE_KEY, USE_MOCK_INSTANCE_DEFAULT));
-    String instance = opts.prop.getProperty(ACCUMULO_INSTANCE_NAME_KEY);
-    String zookeepers = opts.prop.getProperty(ZOOKEEPERS_KEY);
+    Properties props = new Properties();
+    if (opts.prop != null) {
+      props = opts.prop;
+    } else {
+      try (InputStream is = this.getClass().getClassLoader().getResourceAsStream("proxy.properties")) {
+        if (is != null) {
+          props.load(is);
+        } else {
+          System.err.println("proxy.properties needs to be specified as argument (using -p) or on the classpath (by putting the file in conf/)");
+          System.exit(-1);
+        }
+      }
+    }
+
+    boolean useMini = Boolean.parseBoolean(props.getProperty(USE_MINI_ACCUMULO_KEY, USE_MINI_ACCUMULO_DEFAULT));
+    boolean useMock = Boolean.parseBoolean(props.getProperty(USE_MOCK_INSTANCE_KEY, USE_MOCK_INSTANCE_DEFAULT));
+    String instance = props.getProperty(ACCUMULO_INSTANCE_NAME_KEY);
+    String zookeepers = props.getProperty(ZOOKEEPERS_KEY);
 
     if (!useMini && !useMock && instance == null) {
       System.err.println("Properties file must contain one of : useMiniAccumulo=true, useMockInstance=true, or instance=<instance name>");
@@ -132,7 +156,7 @@
       System.exit(1);
     }
 
-    if (!opts.prop.containsKey("port")) {
+    if (!props.containsKey("port")) {
       System.err.println("No port property");
       System.exit(1);
     }
@@ -142,8 +166,8 @@
       final File folder = Files.createTempDirectory(System.currentTimeMillis() + "").toFile();
       final MiniAccumuloCluster accumulo = new MiniAccumuloCluster(folder, "secret");
       accumulo.start();
-      opts.prop.setProperty("instance", accumulo.getConfig().getInstanceName());
-      opts.prop.setProperty("zookeepers", accumulo.getZooKeepers());
+      props.setProperty("instance", accumulo.getConfig().getInstanceName());
+      props.setProperty("zookeepers", accumulo.getZooKeepers());
       Runtime.getRuntime().addShutdownHook(new Thread() {
         @Override
         public void start() {
@@ -153,24 +177,24 @@
             throw new RuntimeException();
           } finally {
             if (!folder.delete())
-              log.warn("Unexpected error removing " + folder);
+              log.warn("Unexpected error removing {}", folder);
           }
         }
       });
     }
 
-    Class<? extends TProtocolFactory> protoFactoryClass = Class.forName(opts.prop.getProperty("protocolFactory", TCompactProtocol.Factory.class.getName()))
+    Class<? extends TProtocolFactory> protoFactoryClass = Class.forName(props.getProperty("protocolFactory", TCompactProtocol.Factory.class.getName()))
         .asSubclass(TProtocolFactory.class);
     TProtocolFactory protoFactory = protoFactoryClass.newInstance();
-    int port = Integer.parseInt(opts.prop.getProperty("port"));
-    String hostname = opts.prop.getProperty(THRIFT_SERVER_HOSTNAME, THRIFT_SERVER_HOSTNAME_DEFAULT);
+    int port = Integer.parseInt(props.getProperty("port"));
+    String hostname = props.getProperty(THRIFT_SERVER_HOSTNAME, THRIFT_SERVER_HOSTNAME_DEFAULT);
     HostAndPort address = HostAndPort.fromParts(hostname, port);
-    ServerAddress server = createProxyServer(address, protoFactory, opts.prop);
+    ServerAddress server = createProxyServer(address, protoFactory, props);
     // Wait for the server to come up
     while (!server.server.isServing()) {
       Thread.sleep(100);
     }
-    log.info("Proxy server started on " + server.getAddress());
+    log.info("Proxy server started on {}", server.getAddress());
     while (server.server.isServing()) {
       Thread.sleep(1000);
     }
@@ -187,7 +211,7 @@
   public static ServerAddress createProxyServer(HostAndPort address, TProtocolFactory protocolFactory, Properties properties, ClientConfiguration clientConf)
       throws Exception {
     final int numThreads = Integer.parseInt(properties.getProperty(THRIFT_THREAD_POOL_SIZE_KEY, THRIFT_THREAD_POOL_SIZE_DEFAULT));
-    final long maxFrameSize = AccumuloConfiguration.getMemoryInBytes(properties.getProperty(THRIFT_MAX_FRAME_SIZE_KEY, THRIFT_MAX_FRAME_SIZE_DEFAULT));
+    final long maxFrameSize = ConfigurationTypeHelper.getFixedMemoryAsBytes(properties.getProperty(THRIFT_MAX_FRAME_SIZE_KEY, THRIFT_MAX_FRAME_SIZE_DEFAULT));
     final int simpleTimerThreadpoolSize = Integer.parseInt(Property.GENERAL_SIMPLETIMER_THREADPOOL_SIZE.getDefaultValue());
     // How frequently to try to resize the thread pool
     final long threadpoolResizeInterval = 1000l * 5;
@@ -201,7 +225,7 @@
     ProxyServer impl = new ProxyServer(properties);
 
     // Wrap the implementation -- translate some exceptions
-    AccumuloProxy.Iface wrappedImpl = RpcWrapper.service(impl, new AccumuloProxy.Processor<AccumuloProxy.Iface>(impl));
+    AccumuloProxy.Iface wrappedImpl = RpcWrapper.service(impl);
 
     // Create the processor from the implementation
     TProcessor processor = new AccumuloProxy.Processor<>(wrappedImpl);
@@ -243,7 +267,7 @@
         }
         UserGroupInformation.loginUserFromKeytab(kerberosPrincipal, kerberosKeytab);
         UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
-        log.info("Logged in as " + ugi.getUserName());
+        log.info("Logged in as {}", ugi.getUserName());
 
         // The kerberosPrimary set in the SASL server needs to match the principal we're logged in as.
         final String shortName = ugi.getShortUserName();
diff --git a/src/main/java/org/apache/accumulo/proxy/ProxyServer.java b/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
index 5e02cb6..9478cc6 100644
--- a/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
+++ b/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
@@ -65,7 +65,7 @@
 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.Namespace;
 import org.apache.accumulo.core.client.impl.thrift.TableOperationExceptionType;
 import org.apache.accumulo.core.client.impl.thrift.ThriftTableOperationException;
 import org.apache.accumulo.core.client.security.SecurityErrorCode;
@@ -1468,8 +1468,8 @@
       Set<String> propertiesToExclude) throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
       org.apache.accumulo.proxy.thrift.TableNotFoundException, org.apache.accumulo.proxy.thrift.TableExistsException, TException {
     try {
-      propertiesToExclude = propertiesToExclude == null ? new HashSet<String>() : propertiesToExclude;
-      propertiesToSet = propertiesToSet == null ? new HashMap<String,String>() : propertiesToSet;
+      propertiesToExclude = propertiesToExclude == null ? new HashSet<>() : propertiesToExclude;
+      propertiesToSet = propertiesToSet == null ? new HashMap<>() : propertiesToSet;
 
       getConnector(login).tableOperations().clone(tableName, newTableName, flush, propertiesToSet, propertiesToExclude);
     } catch (Exception e) {
@@ -1603,12 +1603,12 @@
 
   @Override
   public String systemNamespace() throws TException {
-    return Namespaces.ACCUMULO_NAMESPACE;
+    return Namespace.ACCUMULO;
   }
 
   @Override
   public String defaultNamespace() throws TException {
-    return Namespaces.DEFAULT_NAMESPACE;
+    return Namespace.DEFAULT;
   }
 
   @Override
@@ -1848,7 +1848,7 @@
     if (ThriftServerType.SASL == serverType) {
       String remoteUser = UGIAssumingProcessor.rpcPrincipal();
       if (null == remoteUser || !remoteUser.equals(principal)) {
-        logger.error("Denying login from user " + remoteUser + " who attempted to log in as " + principal);
+        logger.error("Denying login from user {} who attempted to log in as {}", remoteUser, principal);
         throw new org.apache.accumulo.proxy.thrift.AccumuloSecurityException(RPC_ACCUMULO_PRINCIPAL_MISMATCH_MSG);
       }
     }
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 76dd4bc..2292638 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloException.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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 AccumuloException extends TException implements org.apache.thrift.TBase<AccumuloException, AccumuloException._Fields>, java.io.Serializable, Cloneable, Comparable<AccumuloException> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class AccumuloException extends org.apache.thrift.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);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new AccumuloExceptionStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new AccumuloExceptionTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new AccumuloExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new AccumuloExceptionTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(AccumuloException.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public AccumuloException(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public AccumuloException setMsg(String msg) {
+  public AccumuloException setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof AccumuloException)
@@ -231,6 +201,8 @@
   public boolean equals(AccumuloException that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("AccumuloException(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("AccumuloException(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class AccumuloExceptionStandardSchemeFactory implements SchemeFactory {
+  private static class AccumuloExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public AccumuloExceptionStandardScheme getScheme() {
       return new AccumuloExceptionStandardScheme();
     }
   }
 
-  private static class AccumuloExceptionStandardScheme extends StandardScheme<AccumuloException> {
+  private static class AccumuloExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<AccumuloException> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, AccumuloException struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class AccumuloExceptionTupleSchemeFactory implements SchemeFactory {
+  private static class AccumuloExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public AccumuloExceptionTupleScheme getScheme() {
       return new AccumuloExceptionTupleScheme();
     }
   }
 
-  private static class AccumuloExceptionTupleScheme extends TupleScheme<AccumuloException> {
+  private static class AccumuloExceptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<AccumuloException> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, AccumuloException struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, AccumuloException struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(1);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 150de3e..518146b 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloProxy.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloProxy.java
@@ -15,453 +15,426 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 public class AccumuloProxy {
 
   public interface Iface {
 
-    public ByteBuffer login(String principal, Map<String,String> loginProperties) throws AccumuloSecurityException, org.apache.thrift.TException;
+    public java.nio.ByteBuffer login(java.lang.String principal, java.util.Map<java.lang.String,java.lang.String> loginProperties) throws AccumuloSecurityException, org.apache.thrift.TException;
 
-    public int addConstraint(ByteBuffer login, String tableName, String constraintClassName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public int addConstraint(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String constraintClassName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void addSplits(ByteBuffer login, String tableName, Set<ByteBuffer> splits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void addSplits(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> splits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void attachIterator(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes) throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException;
+    public void attachIterator(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes) throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void checkIteratorConflicts(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes) throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException;
+    public void checkIteratorConflicts(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes) throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void clearLocatorCache(ByteBuffer login, String tableName) throws TableNotFoundException, org.apache.thrift.TException;
+    public void clearLocatorCache(java.nio.ByteBuffer login, java.lang.String tableName) throws TableNotFoundException, org.apache.thrift.TException;
 
-    public void cloneTable(ByteBuffer login, String tableName, String newTableName, boolean flush, Map<String,String> propertiesToSet, Set<String> propertiesToExclude) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException;
+    public void cloneTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String newTableName, boolean flush, java.util.Map<java.lang.String,java.lang.String> propertiesToSet, java.util.Set<java.lang.String> propertiesToExclude) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException;
 
-    public void compactTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy) throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException;
+    public void compactTable(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, java.util.List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy) throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException;
 
-    public void cancelCompaction(ByteBuffer login, String tableName) throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException;
+    public void cancelCompaction(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException;
 
-    public void createTable(ByteBuffer login, String tableName, boolean versioningIter, TimeType type) throws AccumuloException, AccumuloSecurityException, TableExistsException, org.apache.thrift.TException;
+    public void createTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean versioningIter, TimeType type) throws AccumuloException, AccumuloSecurityException, TableExistsException, org.apache.thrift.TException;
 
-    public void deleteTable(ByteBuffer login, String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void deleteTable(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void deleteRows(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void deleteRows(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void exportTable(ByteBuffer login, String tableName, String exportDir) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void exportTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String exportDir) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void flushTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void flushTable(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public List<DiskUsage> getDiskUsage(ByteBuffer login, Set<String> tables) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.util.List<DiskUsage> getDiskUsage(java.nio.ByteBuffer login, java.util.Set<java.lang.String> tables) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public Map<String,Set<String>> getLocalityGroups(ByteBuffer login, String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getLocalityGroups(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public IteratorSetting getIteratorSetting(ByteBuffer login, String tableName, String iteratorName, IteratorScope scope) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public IteratorSetting getIteratorSetting(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iteratorName, IteratorScope scope) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public ByteBuffer getMaxRow(ByteBuffer login, String tableName, Set<ByteBuffer> auths, ByteBuffer startRow, boolean startInclusive, ByteBuffer endRow, boolean endInclusive) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.nio.ByteBuffer getMaxRow(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> auths, java.nio.ByteBuffer startRow, boolean startInclusive, java.nio.ByteBuffer endRow, boolean endInclusive) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public Map<String,String> getTableProperties(ByteBuffer login, String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.util.Map<java.lang.String,java.lang.String> getTableProperties(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void importDirectory(ByteBuffer login, String tableName, String importDir, String failureDir, boolean setTime) throws TableNotFoundException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void importDirectory(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir, java.lang.String failureDir, boolean setTime) throws TableNotFoundException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void importTable(ByteBuffer login, String tableName, String importDir) throws TableExistsException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void importTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir) throws TableExistsException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public List<ByteBuffer> listSplits(ByteBuffer login, String tableName, int maxSplits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.util.List<java.nio.ByteBuffer> listSplits(java.nio.ByteBuffer login, java.lang.String tableName, int maxSplits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public Set<String> listTables(ByteBuffer login) throws org.apache.thrift.TException;
+    public java.util.Set<java.lang.String> listTables(java.nio.ByteBuffer login) throws org.apache.thrift.TException;
 
-    public Map<String,Set<IteratorScope>> listIterators(ByteBuffer login, String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> listIterators(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public Map<String,Integer> listConstraints(ByteBuffer login, String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.util.Map<java.lang.String,java.lang.Integer> listConstraints(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void mergeTablets(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void mergeTablets(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void offlineTable(ByteBuffer login, String tableName, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void offlineTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void onlineTable(ByteBuffer login, String tableName, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void onlineTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void removeConstraint(ByteBuffer login, String tableName, int constraint) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void removeConstraint(java.nio.ByteBuffer login, java.lang.String tableName, int constraint) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void removeIterator(ByteBuffer login, String tableName, String iterName, Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void removeIterator(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iterName, java.util.Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void removeTableProperty(ByteBuffer login, String tableName, String property) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void removeTableProperty(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void renameTable(ByteBuffer login, String oldTableName, String newTableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException;
+    public void renameTable(java.nio.ByteBuffer login, java.lang.String oldTableName, java.lang.String newTableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException;
 
-    public void setLocalityGroups(ByteBuffer login, String tableName, Map<String,Set<String>> groups) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void setLocalityGroups(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void setTableProperty(ByteBuffer login, String tableName, String property, String value) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void setTableProperty(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property, java.lang.String value) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public Set<Range> splitRangeByTablets(ByteBuffer login, String tableName, Range range, int maxSplits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.util.Set<Range> splitRangeByTablets(java.nio.ByteBuffer login, java.lang.String tableName, Range range, int maxSplits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public boolean tableExists(ByteBuffer login, String tableName) throws org.apache.thrift.TException;
+    public boolean tableExists(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException;
 
-    public Map<String,String> tableIdMap(ByteBuffer login) throws org.apache.thrift.TException;
+    public java.util.Map<java.lang.String,java.lang.String> tableIdMap(java.nio.ByteBuffer login) throws org.apache.thrift.TException;
 
-    public boolean testTableClassLoad(ByteBuffer login, String tableName, String className, String asTypeName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public boolean testTableClassLoad(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String className, java.lang.String asTypeName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void pingTabletServer(ByteBuffer login, String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void pingTabletServer(java.nio.ByteBuffer login, java.lang.String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public List<ActiveScan> getActiveScans(ByteBuffer login, String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public java.util.List<ActiveScan> getActiveScans(java.nio.ByteBuffer login, java.lang.String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public List<ActiveCompaction> getActiveCompactions(ByteBuffer login, String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public java.util.List<ActiveCompaction> getActiveCompactions(java.nio.ByteBuffer login, java.lang.String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public Map<String,String> getSiteConfiguration(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public java.util.Map<java.lang.String,java.lang.String> getSiteConfiguration(java.nio.ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public Map<String,String> getSystemConfiguration(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public java.util.Map<java.lang.String,java.lang.String> getSystemConfiguration(java.nio.ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public List<String> getTabletServers(ByteBuffer login) throws org.apache.thrift.TException;
+    public java.util.List<java.lang.String> getTabletServers(java.nio.ByteBuffer login) throws org.apache.thrift.TException;
 
-    public void removeProperty(ByteBuffer login, String property) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void removeProperty(java.nio.ByteBuffer login, java.lang.String property) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void setProperty(ByteBuffer login, String property, String value) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void setProperty(java.nio.ByteBuffer login, java.lang.String property, java.lang.String value) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public boolean testClassLoad(ByteBuffer login, String className, String asTypeName) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public boolean testClassLoad(java.nio.ByteBuffer login, java.lang.String className, java.lang.String asTypeName) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public boolean authenticateUser(ByteBuffer login, String user, Map<String,String> properties) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public boolean authenticateUser(java.nio.ByteBuffer login, java.lang.String user, java.util.Map<java.lang.String,java.lang.String> properties) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void changeUserAuthorizations(ByteBuffer login, String user, Set<ByteBuffer> authorizations) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void changeUserAuthorizations(java.nio.ByteBuffer login, java.lang.String user, java.util.Set<java.nio.ByteBuffer> authorizations) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void changeLocalUserPassword(ByteBuffer login, String user, ByteBuffer password) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void changeLocalUserPassword(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void createLocalUser(ByteBuffer login, String user, ByteBuffer password) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void createLocalUser(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void dropLocalUser(ByteBuffer login, String user) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void dropLocalUser(java.nio.ByteBuffer login, java.lang.String user) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public List<ByteBuffer> getUserAuthorizations(ByteBuffer login, String user) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public java.util.List<java.nio.ByteBuffer> getUserAuthorizations(java.nio.ByteBuffer login, java.lang.String user) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void grantSystemPermission(ByteBuffer login, String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void grantSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void grantTablePermission(ByteBuffer login, String user, String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void grantTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public boolean hasSystemPermission(ByteBuffer login, String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public boolean hasSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public boolean hasTablePermission(ByteBuffer login, String user, String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public boolean hasTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public Set<String> listLocalUsers(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.util.Set<java.lang.String> listLocalUsers(java.nio.ByteBuffer login) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void revokeSystemPermission(ByteBuffer login, String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public void revokeSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void revokeTablePermission(ByteBuffer login, String user, String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public void revokeTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.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 void grantNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.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 boolean hasNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.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 void revokeNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.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 java.lang.String createBatchScanner(java.nio.ByteBuffer login, java.lang.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;
+    public java.lang.String createScanner(java.nio.ByteBuffer login, java.lang.String tableName, ScanOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public boolean hasNext(String scanner) throws UnknownScanner, org.apache.thrift.TException;
+    public boolean hasNext(java.lang.String scanner) throws UnknownScanner, org.apache.thrift.TException;
 
-    public KeyValueAndPeek nextEntry(String scanner) throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException;
+    public KeyValueAndPeek nextEntry(java.lang.String scanner) throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public ScanResult nextK(String scanner, int k) throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException;
+    public ScanResult nextK(java.lang.String scanner, int k) throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void closeScanner(String scanner) throws UnknownScanner, org.apache.thrift.TException;
+    public void closeScanner(java.lang.String scanner) throws UnknownScanner, org.apache.thrift.TException;
 
-    public void updateAndFlush(ByteBuffer login, String tableName, Map<ByteBuffer,List<ColumnUpdate>> cells) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, MutationsRejectedException, org.apache.thrift.TException;
+    public void updateAndFlush(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, MutationsRejectedException, org.apache.thrift.TException;
 
-    public String createWriter(ByteBuffer login, String tableName, WriterOptions opts) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.lang.String createWriter(java.nio.ByteBuffer login, java.lang.String tableName, WriterOptions opts) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public void update(String writer, Map<ByteBuffer,List<ColumnUpdate>> cells) throws org.apache.thrift.TException;
+    public void update(java.lang.String writer, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) throws org.apache.thrift.TException;
 
-    public void flush(String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException;
+    public void flush(java.lang.String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException;
 
-    public void closeWriter(String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException;
+    public void closeWriter(java.lang.String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException;
 
-    public ConditionalStatus updateRowConditionally(ByteBuffer login, String tableName, ByteBuffer row, ConditionalUpdates updates) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public ConditionalStatus updateRowConditionally(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer row, ConditionalUpdates updates) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public String createConditionalWriter(ByteBuffer login, String tableName, ConditionalWriterOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
+    public java.lang.String createConditionalWriter(java.nio.ByteBuffer login, java.lang.String tableName, ConditionalWriterOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException;
 
-    public Map<ByteBuffer,ConditionalStatus> updateRowsConditionally(String conditionalWriter, Map<ByteBuffer,ConditionalUpdates> updates) throws UnknownWriter, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public java.util.Map<java.nio.ByteBuffer,ConditionalStatus> updateRowsConditionally(java.lang.String conditionalWriter, java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates) throws UnknownWriter, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public void closeConditionalWriter(String conditionalWriter) throws org.apache.thrift.TException;
+    public void closeConditionalWriter(java.lang.String conditionalWriter) throws org.apache.thrift.TException;
 
-    public Range getRowRange(ByteBuffer row) throws org.apache.thrift.TException;
+    public Range getRowRange(java.nio.ByteBuffer row) throws org.apache.thrift.TException;
 
     public Key getFollowing(Key key, PartialKey part) throws org.apache.thrift.TException;
 
-    public String systemNamespace() throws org.apache.thrift.TException;
+    public java.lang.String systemNamespace() throws org.apache.thrift.TException;
 
-    public String defaultNamespace() throws org.apache.thrift.TException;
+    public java.lang.String defaultNamespace() throws org.apache.thrift.TException;
 
-    public List<String> listNamespaces(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public java.util.List<java.lang.String> listNamespaces(java.nio.ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
 
-    public boolean namespaceExists(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException;
+    public boolean namespaceExists(java.nio.ByteBuffer login, java.lang.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 createNamespace(java.nio.ByteBuffer login, java.lang.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 deleteNamespace(java.nio.ByteBuffer login, java.lang.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 renameNamespace(java.nio.ByteBuffer login, java.lang.String oldNamespaceName, java.lang.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 setNamespaceProperty(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property, java.lang.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 void removeNamespaceProperty(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.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 java.util.Map<java.lang.String,java.lang.String> getNamespaceProperties(java.nio.ByteBuffer login, java.lang.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 java.util.Map<java.lang.String,java.lang.String> namespaceIdMap(java.nio.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 attachNamespaceIterator(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.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 void removeNamespaceIterator(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, java.util.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 IteratorSetting getNamespaceIteratorSetting(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.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 java.util.Map<java.lang.String,java.util.Set<IteratorScope>> listNamespaceIterators(java.nio.ByteBuffer login, java.lang.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 void checkNamespaceIteratorConflicts(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.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 int addNamespaceConstraint(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.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 void removeNamespaceConstraint(java.nio.ByteBuffer login, java.lang.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 java.util.Map<java.lang.String,java.lang.Integer> listNamespaceConstraints(java.nio.ByteBuffer login, java.lang.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 boolean testNamespaceClassLoad(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String className, java.lang.String asTypeName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException;
 
   }
 
   public interface AsyncIface {
 
-    public void login(String principal, Map<String,String> loginProperties, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void login(java.lang.String principal, java.util.Map<java.lang.String,java.lang.String> loginProperties, org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer> resultHandler) throws org.apache.thrift.TException;
 
-    public void addConstraint(ByteBuffer login, String tableName, String constraintClassName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void addConstraint(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String constraintClassName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException;
 
-    public void addSplits(ByteBuffer login, String tableName, Set<ByteBuffer> splits, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void addSplits(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> splits, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void attachIterator(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void attachIterator(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void checkIteratorConflicts(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void checkIteratorConflicts(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void clearLocatorCache(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void clearLocatorCache(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void cloneTable(ByteBuffer login, String tableName, String newTableName, boolean flush, Map<String,String> propertiesToSet, Set<String> propertiesToExclude, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void cloneTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String newTableName, boolean flush, java.util.Map<java.lang.String,java.lang.String> propertiesToSet, java.util.Set<java.lang.String> propertiesToExclude, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void compactTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void compactTable(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, java.util.List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void cancelCompaction(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void cancelCompaction(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void createTable(ByteBuffer login, String tableName, boolean versioningIter, TimeType type, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void createTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean versioningIter, TimeType type, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void deleteTable(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void deleteTable(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void deleteRows(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void deleteRows(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void exportTable(ByteBuffer login, String tableName, String exportDir, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void exportTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String exportDir, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void flushTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, boolean wait, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void flushTable(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, boolean wait, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void getDiskUsage(ByteBuffer login, Set<String> tables, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getDiskUsage(java.nio.ByteBuffer login, java.util.Set<java.lang.String> tables, org.apache.thrift.async.AsyncMethodCallback<java.util.List<DiskUsage>> resultHandler) throws org.apache.thrift.TException;
 
-    public void getLocalityGroups(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getLocalityGroups(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<java.lang.String>>> resultHandler) throws org.apache.thrift.TException;
 
-    public void getIteratorSetting(ByteBuffer login, String tableName, String iteratorName, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getIteratorSetting(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iteratorName, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> resultHandler) throws org.apache.thrift.TException;
 
-    public void getMaxRow(ByteBuffer login, String tableName, Set<ByteBuffer> auths, ByteBuffer startRow, boolean startInclusive, ByteBuffer endRow, boolean endInclusive, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getMaxRow(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> auths, java.nio.ByteBuffer startRow, boolean startInclusive, java.nio.ByteBuffer endRow, boolean endInclusive, org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer> resultHandler) throws org.apache.thrift.TException;
 
-    public void getTableProperties(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getTableProperties(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException;
 
-    public void importDirectory(ByteBuffer login, String tableName, String importDir, String failureDir, boolean setTime, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void importDirectory(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir, java.lang.String failureDir, boolean setTime, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void importTable(ByteBuffer login, String tableName, String importDir, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void importTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void listSplits(ByteBuffer login, String tableName, int maxSplits, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void listSplits(java.nio.ByteBuffer login, java.lang.String tableName, int maxSplits, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>> resultHandler) throws org.apache.thrift.TException;
 
-    public void listTables(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void listTables(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> resultHandler) throws org.apache.thrift.TException;
 
-    public void listIterators(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void listIterators(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> resultHandler) throws org.apache.thrift.TException;
 
-    public void listConstraints(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void listConstraints(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>> resultHandler) throws org.apache.thrift.TException;
 
-    public void mergeTablets(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void mergeTablets(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void offlineTable(ByteBuffer login, String tableName, boolean wait, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void offlineTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void onlineTable(ByteBuffer login, String tableName, boolean wait, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void onlineTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void removeConstraint(ByteBuffer login, String tableName, int constraint, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void removeConstraint(java.nio.ByteBuffer login, java.lang.String tableName, int constraint, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void removeIterator(ByteBuffer login, String tableName, String iterName, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void removeIterator(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iterName, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void removeTableProperty(ByteBuffer login, String tableName, String property, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void removeTableProperty(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void renameTable(ByteBuffer login, String oldTableName, String newTableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void renameTable(java.nio.ByteBuffer login, java.lang.String oldTableName, java.lang.String newTableName, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void setLocalityGroups(ByteBuffer login, String tableName, Map<String,Set<String>> groups, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void setLocalityGroups(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void setTableProperty(ByteBuffer login, String tableName, String property, String value, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void setTableProperty(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property, java.lang.String value, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void splitRangeByTablets(ByteBuffer login, String tableName, Range range, int maxSplits, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void splitRangeByTablets(java.nio.ByteBuffer login, java.lang.String tableName, Range range, int maxSplits, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<Range>> resultHandler) throws org.apache.thrift.TException;
 
-    public void tableExists(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void tableExists(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;
 
-    public void tableIdMap(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void tableIdMap(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException;
 
-    public void testTableClassLoad(ByteBuffer login, String tableName, String className, String asTypeName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void testTableClassLoad(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String className, java.lang.String asTypeName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;
 
-    public void pingTabletServer(ByteBuffer login, String tserver, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void pingTabletServer(java.nio.ByteBuffer login, java.lang.String tserver, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void getActiveScans(ByteBuffer login, String tserver, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getActiveScans(java.nio.ByteBuffer login, java.lang.String tserver, org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveScan>> resultHandler) throws org.apache.thrift.TException;
 
-    public void getActiveCompactions(ByteBuffer login, String tserver, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getActiveCompactions(java.nio.ByteBuffer login, java.lang.String tserver, org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveCompaction>> resultHandler) throws org.apache.thrift.TException;
 
-    public void getSiteConfiguration(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getSiteConfiguration(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException;
 
-    public void getSystemConfiguration(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getSystemConfiguration(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException;
 
-    public void getTabletServers(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getTabletServers(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> resultHandler) throws org.apache.thrift.TException;
 
-    public void removeProperty(ByteBuffer login, String property, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void removeProperty(java.nio.ByteBuffer login, java.lang.String property, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void setProperty(ByteBuffer login, String property, String value, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void setProperty(java.nio.ByteBuffer login, java.lang.String property, java.lang.String value, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void testClassLoad(ByteBuffer login, String className, String asTypeName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void testClassLoad(java.nio.ByteBuffer login, java.lang.String className, java.lang.String asTypeName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;
 
-    public void authenticateUser(ByteBuffer login, String user, Map<String,String> properties, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void authenticateUser(java.nio.ByteBuffer login, java.lang.String user, java.util.Map<java.lang.String,java.lang.String> properties, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;
 
-    public void changeUserAuthorizations(ByteBuffer login, String user, Set<ByteBuffer> authorizations, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void changeUserAuthorizations(java.nio.ByteBuffer login, java.lang.String user, java.util.Set<java.nio.ByteBuffer> authorizations, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void changeLocalUserPassword(ByteBuffer login, String user, ByteBuffer password, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void changeLocalUserPassword(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void createLocalUser(ByteBuffer login, String user, ByteBuffer password, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void createLocalUser(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void dropLocalUser(ByteBuffer login, String user, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void dropLocalUser(java.nio.ByteBuffer login, java.lang.String user, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void getUserAuthorizations(ByteBuffer login, String user, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getUserAuthorizations(java.nio.ByteBuffer login, java.lang.String user, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>> resultHandler) throws org.apache.thrift.TException;
 
-    public void grantSystemPermission(ByteBuffer login, String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void grantSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void grantTablePermission(ByteBuffer login, String user, String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void grantTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void hasSystemPermission(ByteBuffer login, String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void hasSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;
 
-    public void hasTablePermission(ByteBuffer login, String user, String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void hasTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;
 
-    public void listLocalUsers(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void listLocalUsers(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> resultHandler) throws org.apache.thrift.TException;
 
-    public void revokeSystemPermission(ByteBuffer login, String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void revokeSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void revokeTablePermission(ByteBuffer login, String user, String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void revokeTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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 grantNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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 hasNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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 revokeNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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 createBatchScanner(java.nio.ByteBuffer login, java.lang.String tableName, BatchScanOptions options, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> 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;
+    public void createScanner(java.nio.ByteBuffer login, java.lang.String tableName, ScanOptions options, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;
 
-    public void hasNext(String scanner, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void hasNext(java.lang.String scanner, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;
 
-    public void nextEntry(String scanner, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void nextEntry(java.lang.String scanner, org.apache.thrift.async.AsyncMethodCallback<KeyValueAndPeek> resultHandler) throws org.apache.thrift.TException;
 
-    public void nextK(String scanner, int k, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void nextK(java.lang.String scanner, int k, org.apache.thrift.async.AsyncMethodCallback<ScanResult> resultHandler) throws org.apache.thrift.TException;
 
-    public void closeScanner(String scanner, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void closeScanner(java.lang.String scanner, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void updateAndFlush(ByteBuffer login, String tableName, Map<ByteBuffer,List<ColumnUpdate>> cells, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void updateAndFlush(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void createWriter(ByteBuffer login, String tableName, WriterOptions opts, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void createWriter(java.nio.ByteBuffer login, java.lang.String tableName, WriterOptions opts, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;
 
-    public void update(String writer, Map<ByteBuffer,List<ColumnUpdate>> cells, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void update(java.lang.String writer, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void flush(String writer, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void flush(java.lang.String writer, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void closeWriter(String writer, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void closeWriter(java.lang.String writer, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void updateRowConditionally(ByteBuffer login, String tableName, ByteBuffer row, ConditionalUpdates updates, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void updateRowConditionally(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer row, ConditionalUpdates updates, org.apache.thrift.async.AsyncMethodCallback<ConditionalStatus> resultHandler) throws org.apache.thrift.TException;
 
-    public void createConditionalWriter(ByteBuffer login, String tableName, ConditionalWriterOptions options, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void createConditionalWriter(java.nio.ByteBuffer login, java.lang.String tableName, ConditionalWriterOptions options, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;
 
-    public void updateRowsConditionally(String conditionalWriter, Map<ByteBuffer,ConditionalUpdates> updates, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void updateRowsConditionally(java.lang.String conditionalWriter, java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.nio.ByteBuffer,ConditionalStatus>> resultHandler) throws org.apache.thrift.TException;
 
-    public void closeConditionalWriter(String conditionalWriter, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void closeConditionalWriter(java.lang.String conditionalWriter, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
 
-    public void getRowRange(ByteBuffer row, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getRowRange(java.nio.ByteBuffer row, org.apache.thrift.async.AsyncMethodCallback<Range> resultHandler) throws org.apache.thrift.TException;
 
-    public void getFollowing(Key key, PartialKey part, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void getFollowing(Key key, PartialKey part, org.apache.thrift.async.AsyncMethodCallback<Key> resultHandler) throws org.apache.thrift.TException;
 
-    public void systemNamespace(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void systemNamespace(org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;
 
-    public void defaultNamespace(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void defaultNamespace(org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;
 
-    public void listNamespaces(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void listNamespaces(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> 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 namespaceExists(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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 createNamespace(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<Void> 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 deleteNamespace(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<Void> 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 renameNamespace(java.nio.ByteBuffer login, java.lang.String oldNamespaceName, java.lang.String newNamespaceName, org.apache.thrift.async.AsyncMethodCallback<Void> 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 setNamespaceProperty(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property, java.lang.String value, org.apache.thrift.async.AsyncMethodCallback<Void> 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 removeNamespaceProperty(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property, org.apache.thrift.async.AsyncMethodCallback<Void> 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 getNamespaceProperties(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException;
 
-    public void namespaceIdMap(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException;
+    public void namespaceIdMap(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> 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 attachNamespaceIterator(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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 removeNamespaceIterator(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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 getNamespaceIteratorSetting(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> 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 listNamespaceIterators(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> 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 checkNamespaceIteratorConflicts(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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 addNamespaceConstraint(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String constraintClassName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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 removeNamespaceConstraint(java.nio.ByteBuffer login, java.lang.String namespaceName, int id, org.apache.thrift.async.AsyncMethodCallback<Void> 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 listNamespaceConstraints(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>> 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 void testNamespaceClassLoad(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String className, java.lang.String asTypeName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;
 
   }
 
-  public static class Client extends org.apache.thrift.TServiceClient implements Iface {
+  public static class Client extends org.apache.accumulo.core.rpc.TServiceClientWrapper implements Iface {
     public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
       public Factory() {}
       public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
@@ -481,13 +454,13 @@
       super(iprot, oprot);
     }
 
-    public ByteBuffer login(String principal, Map<String,String> loginProperties) throws AccumuloSecurityException, org.apache.thrift.TException
+    public java.nio.ByteBuffer login(java.lang.String principal, java.util.Map<java.lang.String,java.lang.String> loginProperties) throws AccumuloSecurityException, org.apache.thrift.TException
     {
       send_login(principal, loginProperties);
       return recv_login();
     }
 
-    public void send_login(String principal, Map<String,String> loginProperties) throws org.apache.thrift.TException
+    public void send_login(java.lang.String principal, java.util.Map<java.lang.String,java.lang.String> loginProperties) throws org.apache.thrift.TException
     {
       login_args args = new login_args();
       args.setPrincipal(principal);
@@ -495,7 +468,7 @@
       sendBase("login", args);
     }
 
-    public ByteBuffer recv_login() throws AccumuloSecurityException, org.apache.thrift.TException
+    public java.nio.ByteBuffer recv_login() throws AccumuloSecurityException, org.apache.thrift.TException
     {
       login_result result = new login_result();
       receiveBase(result, "login");
@@ -508,13 +481,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "login failed: unknown result");
     }
 
-    public int addConstraint(ByteBuffer login, String tableName, String constraintClassName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public int addConstraint(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String constraintClassName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_addConstraint(login, tableName, constraintClassName);
       return recv_addConstraint();
     }
 
-    public void send_addConstraint(ByteBuffer login, String tableName, String constraintClassName) throws org.apache.thrift.TException
+    public void send_addConstraint(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String constraintClassName) throws org.apache.thrift.TException
     {
       addConstraint_args args = new addConstraint_args();
       args.setLogin(login);
@@ -542,13 +515,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addConstraint failed: unknown result");
     }
 
-    public void addSplits(ByteBuffer login, String tableName, Set<ByteBuffer> splits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void addSplits(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> splits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_addSplits(login, tableName, splits);
       recv_addSplits();
     }
 
-    public void send_addSplits(ByteBuffer login, String tableName, Set<ByteBuffer> splits) throws org.apache.thrift.TException
+    public void send_addSplits(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> splits) throws org.apache.thrift.TException
     {
       addSplits_args args = new addSplits_args();
       args.setLogin(login);
@@ -573,13 +546,13 @@
       return;
     }
 
-    public void attachIterator(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes) throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException
+    public void attachIterator(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes) throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException
     {
       send_attachIterator(login, tableName, setting, scopes);
       recv_attachIterator();
     }
 
-    public void send_attachIterator(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes) throws org.apache.thrift.TException
+    public void send_attachIterator(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes) throws org.apache.thrift.TException
     {
       attachIterator_args args = new attachIterator_args();
       args.setLogin(login);
@@ -605,13 +578,13 @@
       return;
     }
 
-    public void checkIteratorConflicts(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes) throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException
+    public void checkIteratorConflicts(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes) throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException
     {
       send_checkIteratorConflicts(login, tableName, setting, scopes);
       recv_checkIteratorConflicts();
     }
 
-    public void send_checkIteratorConflicts(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes) throws org.apache.thrift.TException
+    public void send_checkIteratorConflicts(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes) throws org.apache.thrift.TException
     {
       checkIteratorConflicts_args args = new checkIteratorConflicts_args();
       args.setLogin(login);
@@ -637,13 +610,13 @@
       return;
     }
 
-    public void clearLocatorCache(ByteBuffer login, String tableName) throws TableNotFoundException, org.apache.thrift.TException
+    public void clearLocatorCache(java.nio.ByteBuffer login, java.lang.String tableName) throws TableNotFoundException, org.apache.thrift.TException
     {
       send_clearLocatorCache(login, tableName);
       recv_clearLocatorCache();
     }
 
-    public void send_clearLocatorCache(ByteBuffer login, String tableName) throws org.apache.thrift.TException
+    public void send_clearLocatorCache(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
     {
       clearLocatorCache_args args = new clearLocatorCache_args();
       args.setLogin(login);
@@ -661,13 +634,13 @@
       return;
     }
 
-    public void cloneTable(ByteBuffer login, String tableName, String newTableName, boolean flush, Map<String,String> propertiesToSet, Set<String> propertiesToExclude) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException
+    public void cloneTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String newTableName, boolean flush, java.util.Map<java.lang.String,java.lang.String> propertiesToSet, java.util.Set<java.lang.String> propertiesToExclude) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException
     {
       send_cloneTable(login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude);
       recv_cloneTable();
     }
 
-    public void send_cloneTable(ByteBuffer login, String tableName, String newTableName, boolean flush, Map<String,String> propertiesToSet, Set<String> propertiesToExclude) throws org.apache.thrift.TException
+    public void send_cloneTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String newTableName, boolean flush, java.util.Map<java.lang.String,java.lang.String> propertiesToSet, java.util.Set<java.lang.String> propertiesToExclude) throws org.apache.thrift.TException
     {
       cloneTable_args args = new cloneTable_args();
       args.setLogin(login);
@@ -698,13 +671,13 @@
       return;
     }
 
-    public void compactTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy) throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException
+    public void compactTable(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, java.util.List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy) throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException
     {
       send_compactTable(login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy);
       recv_compactTable();
     }
 
-    public void send_compactTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy) throws org.apache.thrift.TException
+    public void send_compactTable(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, java.util.List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy) throws org.apache.thrift.TException
     {
       compactTable_args args = new compactTable_args();
       args.setLogin(login);
@@ -734,13 +707,13 @@
       return;
     }
 
-    public void cancelCompaction(ByteBuffer login, String tableName) throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException
+    public void cancelCompaction(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException
     {
       send_cancelCompaction(login, tableName);
       recv_cancelCompaction();
     }
 
-    public void send_cancelCompaction(ByteBuffer login, String tableName) throws org.apache.thrift.TException
+    public void send_cancelCompaction(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
     {
       cancelCompaction_args args = new cancelCompaction_args();
       args.setLogin(login);
@@ -764,13 +737,13 @@
       return;
     }
 
-    public void createTable(ByteBuffer login, String tableName, boolean versioningIter, TimeType type) throws AccumuloException, AccumuloSecurityException, TableExistsException, org.apache.thrift.TException
+    public void createTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean versioningIter, TimeType type) throws AccumuloException, AccumuloSecurityException, TableExistsException, org.apache.thrift.TException
     {
       send_createTable(login, tableName, versioningIter, type);
       recv_createTable();
     }
 
-    public void send_createTable(ByteBuffer login, String tableName, boolean versioningIter, TimeType type) throws org.apache.thrift.TException
+    public void send_createTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean versioningIter, TimeType type) throws org.apache.thrift.TException
     {
       createTable_args args = new createTable_args();
       args.setLogin(login);
@@ -796,13 +769,13 @@
       return;
     }
 
-    public void deleteTable(ByteBuffer login, String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void deleteTable(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_deleteTable(login, tableName);
       recv_deleteTable();
     }
 
-    public void send_deleteTable(ByteBuffer login, String tableName) throws org.apache.thrift.TException
+    public void send_deleteTable(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
     {
       deleteTable_args args = new deleteTable_args();
       args.setLogin(login);
@@ -826,13 +799,13 @@
       return;
     }
 
-    public void deleteRows(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void deleteRows(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_deleteRows(login, tableName, startRow, endRow);
       recv_deleteRows();
     }
 
-    public void send_deleteRows(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow) throws org.apache.thrift.TException
+    public void send_deleteRows(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow) throws org.apache.thrift.TException
     {
       deleteRows_args args = new deleteRows_args();
       args.setLogin(login);
@@ -858,13 +831,13 @@
       return;
     }
 
-    public void exportTable(ByteBuffer login, String tableName, String exportDir) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void exportTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String exportDir) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_exportTable(login, tableName, exportDir);
       recv_exportTable();
     }
 
-    public void send_exportTable(ByteBuffer login, String tableName, String exportDir) throws org.apache.thrift.TException
+    public void send_exportTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String exportDir) throws org.apache.thrift.TException
     {
       exportTable_args args = new exportTable_args();
       args.setLogin(login);
@@ -889,13 +862,13 @@
       return;
     }
 
-    public void flushTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void flushTable(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_flushTable(login, tableName, startRow, endRow, wait);
       recv_flushTable();
     }
 
-    public void send_flushTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, boolean wait) throws org.apache.thrift.TException
+    public void send_flushTable(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, boolean wait) throws org.apache.thrift.TException
     {
       flushTable_args args = new flushTable_args();
       args.setLogin(login);
@@ -922,13 +895,13 @@
       return;
     }
 
-    public List<DiskUsage> getDiskUsage(ByteBuffer login, Set<String> tables) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.List<DiskUsage> getDiskUsage(java.nio.ByteBuffer login, java.util.Set<java.lang.String> tables) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_getDiskUsage(login, tables);
       return recv_getDiskUsage();
     }
 
-    public void send_getDiskUsage(ByteBuffer login, Set<String> tables) throws org.apache.thrift.TException
+    public void send_getDiskUsage(java.nio.ByteBuffer login, java.util.Set<java.lang.String> tables) throws org.apache.thrift.TException
     {
       getDiskUsage_args args = new getDiskUsage_args();
       args.setLogin(login);
@@ -936,7 +909,7 @@
       sendBase("getDiskUsage", args);
     }
 
-    public List<DiskUsage> recv_getDiskUsage() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.List<DiskUsage> recv_getDiskUsage() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       getDiskUsage_result result = new getDiskUsage_result();
       receiveBase(result, "getDiskUsage");
@@ -955,13 +928,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getDiskUsage failed: unknown result");
     }
 
-    public Map<String,Set<String>> getLocalityGroups(ByteBuffer login, String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getLocalityGroups(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_getLocalityGroups(login, tableName);
       return recv_getLocalityGroups();
     }
 
-    public void send_getLocalityGroups(ByteBuffer login, String tableName) throws org.apache.thrift.TException
+    public void send_getLocalityGroups(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
     {
       getLocalityGroups_args args = new getLocalityGroups_args();
       args.setLogin(login);
@@ -969,7 +942,7 @@
       sendBase("getLocalityGroups", args);
     }
 
-    public Map<String,Set<String>> recv_getLocalityGroups() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> recv_getLocalityGroups() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       getLocalityGroups_result result = new getLocalityGroups_result();
       receiveBase(result, "getLocalityGroups");
@@ -988,13 +961,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getLocalityGroups failed: unknown result");
     }
 
-    public IteratorSetting getIteratorSetting(ByteBuffer login, String tableName, String iteratorName, IteratorScope scope) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public IteratorSetting getIteratorSetting(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iteratorName, IteratorScope scope) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_getIteratorSetting(login, tableName, iteratorName, scope);
       return recv_getIteratorSetting();
     }
 
-    public void send_getIteratorSetting(ByteBuffer login, String tableName, String iteratorName, IteratorScope scope) throws org.apache.thrift.TException
+    public void send_getIteratorSetting(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iteratorName, IteratorScope scope) throws org.apache.thrift.TException
     {
       getIteratorSetting_args args = new getIteratorSetting_args();
       args.setLogin(login);
@@ -1023,13 +996,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getIteratorSetting failed: unknown result");
     }
 
-    public ByteBuffer getMaxRow(ByteBuffer login, String tableName, Set<ByteBuffer> auths, ByteBuffer startRow, boolean startInclusive, ByteBuffer endRow, boolean endInclusive) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.nio.ByteBuffer getMaxRow(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> auths, java.nio.ByteBuffer startRow, boolean startInclusive, java.nio.ByteBuffer endRow, boolean endInclusive) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_getMaxRow(login, tableName, auths, startRow, startInclusive, endRow, endInclusive);
       return recv_getMaxRow();
     }
 
-    public void send_getMaxRow(ByteBuffer login, String tableName, Set<ByteBuffer> auths, ByteBuffer startRow, boolean startInclusive, ByteBuffer endRow, boolean endInclusive) throws org.apache.thrift.TException
+    public void send_getMaxRow(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> auths, java.nio.ByteBuffer startRow, boolean startInclusive, java.nio.ByteBuffer endRow, boolean endInclusive) throws org.apache.thrift.TException
     {
       getMaxRow_args args = new getMaxRow_args();
       args.setLogin(login);
@@ -1042,7 +1015,7 @@
       sendBase("getMaxRow", args);
     }
 
-    public ByteBuffer recv_getMaxRow() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.nio.ByteBuffer recv_getMaxRow() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       getMaxRow_result result = new getMaxRow_result();
       receiveBase(result, "getMaxRow");
@@ -1061,13 +1034,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getMaxRow failed: unknown result");
     }
 
-    public Map<String,String> getTableProperties(ByteBuffer login, String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.String> getTableProperties(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_getTableProperties(login, tableName);
       return recv_getTableProperties();
     }
 
-    public void send_getTableProperties(ByteBuffer login, String tableName) throws org.apache.thrift.TException
+    public void send_getTableProperties(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
     {
       getTableProperties_args args = new getTableProperties_args();
       args.setLogin(login);
@@ -1075,7 +1048,7 @@
       sendBase("getTableProperties", args);
     }
 
-    public Map<String,String> recv_getTableProperties() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.String> recv_getTableProperties() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       getTableProperties_result result = new getTableProperties_result();
       receiveBase(result, "getTableProperties");
@@ -1094,13 +1067,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getTableProperties failed: unknown result");
     }
 
-    public void importDirectory(ByteBuffer login, String tableName, String importDir, String failureDir, boolean setTime) throws TableNotFoundException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void importDirectory(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir, java.lang.String failureDir, boolean setTime) throws TableNotFoundException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_importDirectory(login, tableName, importDir, failureDir, setTime);
       recv_importDirectory();
     }
 
-    public void send_importDirectory(ByteBuffer login, String tableName, String importDir, String failureDir, boolean setTime) throws org.apache.thrift.TException
+    public void send_importDirectory(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir, java.lang.String failureDir, boolean setTime) throws org.apache.thrift.TException
     {
       importDirectory_args args = new importDirectory_args();
       args.setLogin(login);
@@ -1127,13 +1100,13 @@
       return;
     }
 
-    public void importTable(ByteBuffer login, String tableName, String importDir) throws TableExistsException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void importTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir) throws TableExistsException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_importTable(login, tableName, importDir);
       recv_importTable();
     }
 
-    public void send_importTable(ByteBuffer login, String tableName, String importDir) throws org.apache.thrift.TException
+    public void send_importTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir) throws org.apache.thrift.TException
     {
       importTable_args args = new importTable_args();
       args.setLogin(login);
@@ -1158,13 +1131,13 @@
       return;
     }
 
-    public List<ByteBuffer> listSplits(ByteBuffer login, String tableName, int maxSplits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.List<java.nio.ByteBuffer> listSplits(java.nio.ByteBuffer login, java.lang.String tableName, int maxSplits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_listSplits(login, tableName, maxSplits);
       return recv_listSplits();
     }
 
-    public void send_listSplits(ByteBuffer login, String tableName, int maxSplits) throws org.apache.thrift.TException
+    public void send_listSplits(java.nio.ByteBuffer login, java.lang.String tableName, int maxSplits) throws org.apache.thrift.TException
     {
       listSplits_args args = new listSplits_args();
       args.setLogin(login);
@@ -1173,7 +1146,7 @@
       sendBase("listSplits", args);
     }
 
-    public List<ByteBuffer> recv_listSplits() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.List<java.nio.ByteBuffer> recv_listSplits() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       listSplits_result result = new listSplits_result();
       receiveBase(result, "listSplits");
@@ -1192,20 +1165,20 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listSplits failed: unknown result");
     }
 
-    public Set<String> listTables(ByteBuffer login) throws org.apache.thrift.TException
+    public java.util.Set<java.lang.String> listTables(java.nio.ByteBuffer login) throws org.apache.thrift.TException
     {
       send_listTables(login);
       return recv_listTables();
     }
 
-    public void send_listTables(ByteBuffer login) throws org.apache.thrift.TException
+    public void send_listTables(java.nio.ByteBuffer login) throws org.apache.thrift.TException
     {
       listTables_args args = new listTables_args();
       args.setLogin(login);
       sendBase("listTables", args);
     }
 
-    public Set<String> recv_listTables() throws org.apache.thrift.TException
+    public java.util.Set<java.lang.String> recv_listTables() throws org.apache.thrift.TException
     {
       listTables_result result = new listTables_result();
       receiveBase(result, "listTables");
@@ -1215,13 +1188,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listTables failed: unknown result");
     }
 
-    public Map<String,Set<IteratorScope>> listIterators(ByteBuffer login, String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> listIterators(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_listIterators(login, tableName);
       return recv_listIterators();
     }
 
-    public void send_listIterators(ByteBuffer login, String tableName) throws org.apache.thrift.TException
+    public void send_listIterators(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
     {
       listIterators_args args = new listIterators_args();
       args.setLogin(login);
@@ -1229,7 +1202,7 @@
       sendBase("listIterators", args);
     }
 
-    public Map<String,Set<IteratorScope>> recv_listIterators() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> recv_listIterators() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       listIterators_result result = new listIterators_result();
       receiveBase(result, "listIterators");
@@ -1248,13 +1221,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listIterators failed: unknown result");
     }
 
-    public Map<String,Integer> listConstraints(ByteBuffer login, String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.Integer> listConstraints(java.nio.ByteBuffer login, java.lang.String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_listConstraints(login, tableName);
       return recv_listConstraints();
     }
 
-    public void send_listConstraints(ByteBuffer login, String tableName) throws org.apache.thrift.TException
+    public void send_listConstraints(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
     {
       listConstraints_args args = new listConstraints_args();
       args.setLogin(login);
@@ -1262,7 +1235,7 @@
       sendBase("listConstraints", args);
     }
 
-    public Map<String,Integer> recv_listConstraints() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.Integer> recv_listConstraints() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       listConstraints_result result = new listConstraints_result();
       receiveBase(result, "listConstraints");
@@ -1281,13 +1254,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listConstraints failed: unknown result");
     }
 
-    public void mergeTablets(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void mergeTablets(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_mergeTablets(login, tableName, startRow, endRow);
       recv_mergeTablets();
     }
 
-    public void send_mergeTablets(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow) throws org.apache.thrift.TException
+    public void send_mergeTablets(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow) throws org.apache.thrift.TException
     {
       mergeTablets_args args = new mergeTablets_args();
       args.setLogin(login);
@@ -1313,13 +1286,13 @@
       return;
     }
 
-    public void offlineTable(ByteBuffer login, String tableName, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void offlineTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_offlineTable(login, tableName, wait);
       recv_offlineTable();
     }
 
-    public void send_offlineTable(ByteBuffer login, String tableName, boolean wait) throws org.apache.thrift.TException
+    public void send_offlineTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait) throws org.apache.thrift.TException
     {
       offlineTable_args args = new offlineTable_args();
       args.setLogin(login);
@@ -1344,13 +1317,13 @@
       return;
     }
 
-    public void onlineTable(ByteBuffer login, String tableName, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void onlineTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_onlineTable(login, tableName, wait);
       recv_onlineTable();
     }
 
-    public void send_onlineTable(ByteBuffer login, String tableName, boolean wait) throws org.apache.thrift.TException
+    public void send_onlineTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait) throws org.apache.thrift.TException
     {
       onlineTable_args args = new onlineTable_args();
       args.setLogin(login);
@@ -1375,13 +1348,13 @@
       return;
     }
 
-    public void removeConstraint(ByteBuffer login, String tableName, int constraint) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void removeConstraint(java.nio.ByteBuffer login, java.lang.String tableName, int constraint) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_removeConstraint(login, tableName, constraint);
       recv_removeConstraint();
     }
 
-    public void send_removeConstraint(ByteBuffer login, String tableName, int constraint) throws org.apache.thrift.TException
+    public void send_removeConstraint(java.nio.ByteBuffer login, java.lang.String tableName, int constraint) throws org.apache.thrift.TException
     {
       removeConstraint_args args = new removeConstraint_args();
       args.setLogin(login);
@@ -1406,13 +1379,13 @@
       return;
     }
 
-    public void removeIterator(ByteBuffer login, String tableName, String iterName, Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void removeIterator(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iterName, java.util.Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_removeIterator(login, tableName, iterName, scopes);
       recv_removeIterator();
     }
 
-    public void send_removeIterator(ByteBuffer login, String tableName, String iterName, Set<IteratorScope> scopes) throws org.apache.thrift.TException
+    public void send_removeIterator(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iterName, java.util.Set<IteratorScope> scopes) throws org.apache.thrift.TException
     {
       removeIterator_args args = new removeIterator_args();
       args.setLogin(login);
@@ -1438,13 +1411,13 @@
       return;
     }
 
-    public void removeTableProperty(ByteBuffer login, String tableName, String property) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void removeTableProperty(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_removeTableProperty(login, tableName, property);
       recv_removeTableProperty();
     }
 
-    public void send_removeTableProperty(ByteBuffer login, String tableName, String property) throws org.apache.thrift.TException
+    public void send_removeTableProperty(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property) throws org.apache.thrift.TException
     {
       removeTableProperty_args args = new removeTableProperty_args();
       args.setLogin(login);
@@ -1469,13 +1442,13 @@
       return;
     }
 
-    public void renameTable(ByteBuffer login, String oldTableName, String newTableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException
+    public void renameTable(java.nio.ByteBuffer login, java.lang.String oldTableName, java.lang.String newTableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException
     {
       send_renameTable(login, oldTableName, newTableName);
       recv_renameTable();
     }
 
-    public void send_renameTable(ByteBuffer login, String oldTableName, String newTableName) throws org.apache.thrift.TException
+    public void send_renameTable(java.nio.ByteBuffer login, java.lang.String oldTableName, java.lang.String newTableName) throws org.apache.thrift.TException
     {
       renameTable_args args = new renameTable_args();
       args.setLogin(login);
@@ -1503,13 +1476,13 @@
       return;
     }
 
-    public void setLocalityGroups(ByteBuffer login, String tableName, Map<String,Set<String>> groups) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void setLocalityGroups(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_setLocalityGroups(login, tableName, groups);
       recv_setLocalityGroups();
     }
 
-    public void send_setLocalityGroups(ByteBuffer login, String tableName, Map<String,Set<String>> groups) throws org.apache.thrift.TException
+    public void send_setLocalityGroups(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups) throws org.apache.thrift.TException
     {
       setLocalityGroups_args args = new setLocalityGroups_args();
       args.setLogin(login);
@@ -1534,13 +1507,13 @@
       return;
     }
 
-    public void setTableProperty(ByteBuffer login, String tableName, String property, String value) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void setTableProperty(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property, java.lang.String value) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_setTableProperty(login, tableName, property, value);
       recv_setTableProperty();
     }
 
-    public void send_setTableProperty(ByteBuffer login, String tableName, String property, String value) throws org.apache.thrift.TException
+    public void send_setTableProperty(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property, java.lang.String value) throws org.apache.thrift.TException
     {
       setTableProperty_args args = new setTableProperty_args();
       args.setLogin(login);
@@ -1566,13 +1539,13 @@
       return;
     }
 
-    public Set<Range> splitRangeByTablets(ByteBuffer login, String tableName, Range range, int maxSplits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Set<Range> splitRangeByTablets(java.nio.ByteBuffer login, java.lang.String tableName, Range range, int maxSplits) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_splitRangeByTablets(login, tableName, range, maxSplits);
       return recv_splitRangeByTablets();
     }
 
-    public void send_splitRangeByTablets(ByteBuffer login, String tableName, Range range, int maxSplits) throws org.apache.thrift.TException
+    public void send_splitRangeByTablets(java.nio.ByteBuffer login, java.lang.String tableName, Range range, int maxSplits) throws org.apache.thrift.TException
     {
       splitRangeByTablets_args args = new splitRangeByTablets_args();
       args.setLogin(login);
@@ -1582,7 +1555,7 @@
       sendBase("splitRangeByTablets", args);
     }
 
-    public Set<Range> recv_splitRangeByTablets() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Set<Range> recv_splitRangeByTablets() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       splitRangeByTablets_result result = new splitRangeByTablets_result();
       receiveBase(result, "splitRangeByTablets");
@@ -1601,13 +1574,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "splitRangeByTablets failed: unknown result");
     }
 
-    public boolean tableExists(ByteBuffer login, String tableName) throws org.apache.thrift.TException
+    public boolean tableExists(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
     {
       send_tableExists(login, tableName);
       return recv_tableExists();
     }
 
-    public void send_tableExists(ByteBuffer login, String tableName) throws org.apache.thrift.TException
+    public void send_tableExists(java.nio.ByteBuffer login, java.lang.String tableName) throws org.apache.thrift.TException
     {
       tableExists_args args = new tableExists_args();
       args.setLogin(login);
@@ -1625,20 +1598,20 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "tableExists failed: unknown result");
     }
 
-    public Map<String,String> tableIdMap(ByteBuffer login) throws org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.String> tableIdMap(java.nio.ByteBuffer login) throws org.apache.thrift.TException
     {
       send_tableIdMap(login);
       return recv_tableIdMap();
     }
 
-    public void send_tableIdMap(ByteBuffer login) throws org.apache.thrift.TException
+    public void send_tableIdMap(java.nio.ByteBuffer login) throws org.apache.thrift.TException
     {
       tableIdMap_args args = new tableIdMap_args();
       args.setLogin(login);
       sendBase("tableIdMap", args);
     }
 
-    public Map<String,String> recv_tableIdMap() throws org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.String> recv_tableIdMap() throws org.apache.thrift.TException
     {
       tableIdMap_result result = new tableIdMap_result();
       receiveBase(result, "tableIdMap");
@@ -1648,13 +1621,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "tableIdMap failed: unknown result");
     }
 
-    public boolean testTableClassLoad(ByteBuffer login, String tableName, String className, String asTypeName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public boolean testTableClassLoad(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String className, java.lang.String asTypeName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_testTableClassLoad(login, tableName, className, asTypeName);
       return recv_testTableClassLoad();
     }
 
-    public void send_testTableClassLoad(ByteBuffer login, String tableName, String className, String asTypeName) throws org.apache.thrift.TException
+    public void send_testTableClassLoad(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String className, java.lang.String asTypeName) throws org.apache.thrift.TException
     {
       testTableClassLoad_args args = new testTableClassLoad_args();
       args.setLogin(login);
@@ -1683,13 +1656,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "testTableClassLoad failed: unknown result");
     }
 
-    public void pingTabletServer(ByteBuffer login, String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void pingTabletServer(java.nio.ByteBuffer login, java.lang.String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_pingTabletServer(login, tserver);
       recv_pingTabletServer();
     }
 
-    public void send_pingTabletServer(ByteBuffer login, String tserver) throws org.apache.thrift.TException
+    public void send_pingTabletServer(java.nio.ByteBuffer login, java.lang.String tserver) throws org.apache.thrift.TException
     {
       pingTabletServer_args args = new pingTabletServer_args();
       args.setLogin(login);
@@ -1710,13 +1683,13 @@
       return;
     }
 
-    public List<ActiveScan> getActiveScans(ByteBuffer login, String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.List<ActiveScan> getActiveScans(java.nio.ByteBuffer login, java.lang.String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_getActiveScans(login, tserver);
       return recv_getActiveScans();
     }
 
-    public void send_getActiveScans(ByteBuffer login, String tserver) throws org.apache.thrift.TException
+    public void send_getActiveScans(java.nio.ByteBuffer login, java.lang.String tserver) throws org.apache.thrift.TException
     {
       getActiveScans_args args = new getActiveScans_args();
       args.setLogin(login);
@@ -1724,7 +1697,7 @@
       sendBase("getActiveScans", args);
     }
 
-    public List<ActiveScan> recv_getActiveScans() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.List<ActiveScan> recv_getActiveScans() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       getActiveScans_result result = new getActiveScans_result();
       receiveBase(result, "getActiveScans");
@@ -1740,13 +1713,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getActiveScans failed: unknown result");
     }
 
-    public List<ActiveCompaction> getActiveCompactions(ByteBuffer login, String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.List<ActiveCompaction> getActiveCompactions(java.nio.ByteBuffer login, java.lang.String tserver) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_getActiveCompactions(login, tserver);
       return recv_getActiveCompactions();
     }
 
-    public void send_getActiveCompactions(ByteBuffer login, String tserver) throws org.apache.thrift.TException
+    public void send_getActiveCompactions(java.nio.ByteBuffer login, java.lang.String tserver) throws org.apache.thrift.TException
     {
       getActiveCompactions_args args = new getActiveCompactions_args();
       args.setLogin(login);
@@ -1754,7 +1727,7 @@
       sendBase("getActiveCompactions", args);
     }
 
-    public List<ActiveCompaction> recv_getActiveCompactions() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.List<ActiveCompaction> recv_getActiveCompactions() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       getActiveCompactions_result result = new getActiveCompactions_result();
       receiveBase(result, "getActiveCompactions");
@@ -1770,20 +1743,20 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getActiveCompactions failed: unknown result");
     }
 
-    public Map<String,String> getSiteConfiguration(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.String> getSiteConfiguration(java.nio.ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_getSiteConfiguration(login);
       return recv_getSiteConfiguration();
     }
 
-    public void send_getSiteConfiguration(ByteBuffer login) throws org.apache.thrift.TException
+    public void send_getSiteConfiguration(java.nio.ByteBuffer login) throws org.apache.thrift.TException
     {
       getSiteConfiguration_args args = new getSiteConfiguration_args();
       args.setLogin(login);
       sendBase("getSiteConfiguration", args);
     }
 
-    public Map<String,String> recv_getSiteConfiguration() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.String> recv_getSiteConfiguration() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       getSiteConfiguration_result result = new getSiteConfiguration_result();
       receiveBase(result, "getSiteConfiguration");
@@ -1799,20 +1772,20 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getSiteConfiguration failed: unknown result");
     }
 
-    public Map<String,String> getSystemConfiguration(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.String> getSystemConfiguration(java.nio.ByteBuffer login) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_getSystemConfiguration(login);
       return recv_getSystemConfiguration();
     }
 
-    public void send_getSystemConfiguration(ByteBuffer login) throws org.apache.thrift.TException
+    public void send_getSystemConfiguration(java.nio.ByteBuffer login) throws org.apache.thrift.TException
     {
       getSystemConfiguration_args args = new getSystemConfiguration_args();
       args.setLogin(login);
       sendBase("getSystemConfiguration", args);
     }
 
-    public Map<String,String> recv_getSystemConfiguration() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.String> recv_getSystemConfiguration() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       getSystemConfiguration_result result = new getSystemConfiguration_result();
       receiveBase(result, "getSystemConfiguration");
@@ -1828,20 +1801,20 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getSystemConfiguration failed: unknown result");
     }
 
-    public List<String> getTabletServers(ByteBuffer login) throws org.apache.thrift.TException
+    public java.util.List<java.lang.String> getTabletServers(java.nio.ByteBuffer login) throws org.apache.thrift.TException
     {
       send_getTabletServers(login);
       return recv_getTabletServers();
     }
 
-    public void send_getTabletServers(ByteBuffer login) throws org.apache.thrift.TException
+    public void send_getTabletServers(java.nio.ByteBuffer login) throws org.apache.thrift.TException
     {
       getTabletServers_args args = new getTabletServers_args();
       args.setLogin(login);
       sendBase("getTabletServers", args);
     }
 
-    public List<String> recv_getTabletServers() throws org.apache.thrift.TException
+    public java.util.List<java.lang.String> recv_getTabletServers() throws org.apache.thrift.TException
     {
       getTabletServers_result result = new getTabletServers_result();
       receiveBase(result, "getTabletServers");
@@ -1851,13 +1824,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getTabletServers failed: unknown result");
     }
 
-    public void removeProperty(ByteBuffer login, String property) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void removeProperty(java.nio.ByteBuffer login, java.lang.String property) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_removeProperty(login, property);
       recv_removeProperty();
     }
 
-    public void send_removeProperty(ByteBuffer login, String property) throws org.apache.thrift.TException
+    public void send_removeProperty(java.nio.ByteBuffer login, java.lang.String property) throws org.apache.thrift.TException
     {
       removeProperty_args args = new removeProperty_args();
       args.setLogin(login);
@@ -1878,13 +1851,13 @@
       return;
     }
 
-    public void setProperty(ByteBuffer login, String property, String value) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void setProperty(java.nio.ByteBuffer login, java.lang.String property, java.lang.String value) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_setProperty(login, property, value);
       recv_setProperty();
     }
 
-    public void send_setProperty(ByteBuffer login, String property, String value) throws org.apache.thrift.TException
+    public void send_setProperty(java.nio.ByteBuffer login, java.lang.String property, java.lang.String value) throws org.apache.thrift.TException
     {
       setProperty_args args = new setProperty_args();
       args.setLogin(login);
@@ -1906,13 +1879,13 @@
       return;
     }
 
-    public boolean testClassLoad(ByteBuffer login, String className, String asTypeName) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public boolean testClassLoad(java.nio.ByteBuffer login, java.lang.String className, java.lang.String asTypeName) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_testClassLoad(login, className, asTypeName);
       return recv_testClassLoad();
     }
 
-    public void send_testClassLoad(ByteBuffer login, String className, String asTypeName) throws org.apache.thrift.TException
+    public void send_testClassLoad(java.nio.ByteBuffer login, java.lang.String className, java.lang.String asTypeName) throws org.apache.thrift.TException
     {
       testClassLoad_args args = new testClassLoad_args();
       args.setLogin(login);
@@ -1937,13 +1910,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "testClassLoad failed: unknown result");
     }
 
-    public boolean authenticateUser(ByteBuffer login, String user, Map<String,String> properties) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public boolean authenticateUser(java.nio.ByteBuffer login, java.lang.String user, java.util.Map<java.lang.String,java.lang.String> properties) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_authenticateUser(login, user, properties);
       return recv_authenticateUser();
     }
 
-    public void send_authenticateUser(ByteBuffer login, String user, Map<String,String> properties) throws org.apache.thrift.TException
+    public void send_authenticateUser(java.nio.ByteBuffer login, java.lang.String user, java.util.Map<java.lang.String,java.lang.String> properties) throws org.apache.thrift.TException
     {
       authenticateUser_args args = new authenticateUser_args();
       args.setLogin(login);
@@ -1968,13 +1941,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "authenticateUser failed: unknown result");
     }
 
-    public void changeUserAuthorizations(ByteBuffer login, String user, Set<ByteBuffer> authorizations) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void changeUserAuthorizations(java.nio.ByteBuffer login, java.lang.String user, java.util.Set<java.nio.ByteBuffer> authorizations) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_changeUserAuthorizations(login, user, authorizations);
       recv_changeUserAuthorizations();
     }
 
-    public void send_changeUserAuthorizations(ByteBuffer login, String user, Set<ByteBuffer> authorizations) throws org.apache.thrift.TException
+    public void send_changeUserAuthorizations(java.nio.ByteBuffer login, java.lang.String user, java.util.Set<java.nio.ByteBuffer> authorizations) throws org.apache.thrift.TException
     {
       changeUserAuthorizations_args args = new changeUserAuthorizations_args();
       args.setLogin(login);
@@ -1996,13 +1969,13 @@
       return;
     }
 
-    public void changeLocalUserPassword(ByteBuffer login, String user, ByteBuffer password) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void changeLocalUserPassword(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_changeLocalUserPassword(login, user, password);
       recv_changeLocalUserPassword();
     }
 
-    public void send_changeLocalUserPassword(ByteBuffer login, String user, ByteBuffer password) throws org.apache.thrift.TException
+    public void send_changeLocalUserPassword(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password) throws org.apache.thrift.TException
     {
       changeLocalUserPassword_args args = new changeLocalUserPassword_args();
       args.setLogin(login);
@@ -2024,13 +1997,13 @@
       return;
     }
 
-    public void createLocalUser(ByteBuffer login, String user, ByteBuffer password) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void createLocalUser(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_createLocalUser(login, user, password);
       recv_createLocalUser();
     }
 
-    public void send_createLocalUser(ByteBuffer login, String user, ByteBuffer password) throws org.apache.thrift.TException
+    public void send_createLocalUser(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password) throws org.apache.thrift.TException
     {
       createLocalUser_args args = new createLocalUser_args();
       args.setLogin(login);
@@ -2052,13 +2025,13 @@
       return;
     }
 
-    public void dropLocalUser(ByteBuffer login, String user) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void dropLocalUser(java.nio.ByteBuffer login, java.lang.String user) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_dropLocalUser(login, user);
       recv_dropLocalUser();
     }
 
-    public void send_dropLocalUser(ByteBuffer login, String user) throws org.apache.thrift.TException
+    public void send_dropLocalUser(java.nio.ByteBuffer login, java.lang.String user) throws org.apache.thrift.TException
     {
       dropLocalUser_args args = new dropLocalUser_args();
       args.setLogin(login);
@@ -2079,13 +2052,13 @@
       return;
     }
 
-    public List<ByteBuffer> getUserAuthorizations(ByteBuffer login, String user) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.List<java.nio.ByteBuffer> getUserAuthorizations(java.nio.ByteBuffer login, java.lang.String user) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_getUserAuthorizations(login, user);
       return recv_getUserAuthorizations();
     }
 
-    public void send_getUserAuthorizations(ByteBuffer login, String user) throws org.apache.thrift.TException
+    public void send_getUserAuthorizations(java.nio.ByteBuffer login, java.lang.String user) throws org.apache.thrift.TException
     {
       getUserAuthorizations_args args = new getUserAuthorizations_args();
       args.setLogin(login);
@@ -2093,7 +2066,7 @@
       sendBase("getUserAuthorizations", args);
     }
 
-    public List<ByteBuffer> recv_getUserAuthorizations() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.List<java.nio.ByteBuffer> recv_getUserAuthorizations() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       getUserAuthorizations_result result = new getUserAuthorizations_result();
       receiveBase(result, "getUserAuthorizations");
@@ -2109,13 +2082,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getUserAuthorizations failed: unknown result");
     }
 
-    public void grantSystemPermission(ByteBuffer login, String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void grantSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_grantSystemPermission(login, user, perm);
       recv_grantSystemPermission();
     }
 
-    public void send_grantSystemPermission(ByteBuffer login, String user, SystemPermission perm) throws org.apache.thrift.TException
+    public void send_grantSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws org.apache.thrift.TException
     {
       grantSystemPermission_args args = new grantSystemPermission_args();
       args.setLogin(login);
@@ -2137,13 +2110,13 @@
       return;
     }
 
-    public void grantTablePermission(ByteBuffer login, String user, String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void grantTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_grantTablePermission(login, user, table, perm);
       recv_grantTablePermission();
     }
 
-    public void send_grantTablePermission(ByteBuffer login, String user, String table, TablePermission perm) throws org.apache.thrift.TException
+    public void send_grantTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm) throws org.apache.thrift.TException
     {
       grantTablePermission_args args = new grantTablePermission_args();
       args.setLogin(login);
@@ -2169,13 +2142,13 @@
       return;
     }
 
-    public boolean hasSystemPermission(ByteBuffer login, String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public boolean hasSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_hasSystemPermission(login, user, perm);
       return recv_hasSystemPermission();
     }
 
-    public void send_hasSystemPermission(ByteBuffer login, String user, SystemPermission perm) throws org.apache.thrift.TException
+    public void send_hasSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws org.apache.thrift.TException
     {
       hasSystemPermission_args args = new hasSystemPermission_args();
       args.setLogin(login);
@@ -2200,13 +2173,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "hasSystemPermission failed: unknown result");
     }
 
-    public boolean hasTablePermission(ByteBuffer login, String user, String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public boolean hasTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_hasTablePermission(login, user, table, perm);
       return recv_hasTablePermission();
     }
 
-    public void send_hasTablePermission(ByteBuffer login, String user, String table, TablePermission perm) throws org.apache.thrift.TException
+    public void send_hasTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm) throws org.apache.thrift.TException
     {
       hasTablePermission_args args = new hasTablePermission_args();
       args.setLogin(login);
@@ -2235,20 +2208,20 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "hasTablePermission failed: unknown result");
     }
 
-    public Set<String> listLocalUsers(ByteBuffer login) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Set<java.lang.String> listLocalUsers(java.nio.ByteBuffer login) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_listLocalUsers(login);
       return recv_listLocalUsers();
     }
 
-    public void send_listLocalUsers(ByteBuffer login) throws org.apache.thrift.TException
+    public void send_listLocalUsers(java.nio.ByteBuffer login) throws org.apache.thrift.TException
     {
       listLocalUsers_args args = new listLocalUsers_args();
       args.setLogin(login);
       sendBase("listLocalUsers", args);
     }
 
-    public Set<String> recv_listLocalUsers() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.util.Set<java.lang.String> recv_listLocalUsers() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       listLocalUsers_result result = new listLocalUsers_result();
       receiveBase(result, "listLocalUsers");
@@ -2267,13 +2240,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "listLocalUsers failed: unknown result");
     }
 
-    public void revokeSystemPermission(ByteBuffer login, String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void revokeSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_revokeSystemPermission(login, user, perm);
       recv_revokeSystemPermission();
     }
 
-    public void send_revokeSystemPermission(ByteBuffer login, String user, SystemPermission perm) throws org.apache.thrift.TException
+    public void send_revokeSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm) throws org.apache.thrift.TException
     {
       revokeSystemPermission_args args = new revokeSystemPermission_args();
       args.setLogin(login);
@@ -2295,13 +2268,13 @@
       return;
     }
 
-    public void revokeTablePermission(ByteBuffer login, String user, String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public void revokeTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_revokeTablePermission(login, user, table, perm);
       recv_revokeTablePermission();
     }
 
-    public void send_revokeTablePermission(ByteBuffer login, String user, String table, TablePermission perm) throws org.apache.thrift.TException
+    public void send_revokeTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm) throws org.apache.thrift.TException
     {
       revokeTablePermission_args args = new revokeTablePermission_args();
       args.setLogin(login);
@@ -2327,13 +2300,13 @@
       return;
     }
 
-    public void grantNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public void grantNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.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
+    public void send_grantNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm) throws org.apache.thrift.TException
     {
       grantNamespacePermission_args args = new grantNamespacePermission_args();
       args.setLogin(login);
@@ -2356,13 +2329,13 @@
       return;
     }
 
-    public boolean hasNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm) throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public boolean hasNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.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
+    public void send_hasNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm) throws org.apache.thrift.TException
     {
       hasNamespacePermission_args args = new hasNamespacePermission_args();
       args.setLogin(login);
@@ -2388,13 +2361,13 @@
       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
+    public void revokeNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.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
+    public void send_revokeNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm) throws org.apache.thrift.TException
     {
       revokeNamespacePermission_args args = new revokeNamespacePermission_args();
       args.setLogin(login);
@@ -2417,13 +2390,13 @@
       return;
     }
 
-    public String createBatchScanner(ByteBuffer login, String tableName, BatchScanOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.lang.String createBatchScanner(java.nio.ByteBuffer login, java.lang.String tableName, BatchScanOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_createBatchScanner(login, tableName, options);
       return recv_createBatchScanner();
     }
 
-    public void send_createBatchScanner(ByteBuffer login, String tableName, BatchScanOptions options) throws org.apache.thrift.TException
+    public void send_createBatchScanner(java.nio.ByteBuffer login, java.lang.String tableName, BatchScanOptions options) throws org.apache.thrift.TException
     {
       createBatchScanner_args args = new createBatchScanner_args();
       args.setLogin(login);
@@ -2432,7 +2405,7 @@
       sendBase("createBatchScanner", args);
     }
 
-    public String recv_createBatchScanner() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.lang.String recv_createBatchScanner() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       createBatchScanner_result result = new createBatchScanner_result();
       receiveBase(result, "createBatchScanner");
@@ -2451,13 +2424,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createBatchScanner failed: unknown result");
     }
 
-    public String createScanner(ByteBuffer login, String tableName, ScanOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.lang.String createScanner(java.nio.ByteBuffer login, java.lang.String tableName, ScanOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_createScanner(login, tableName, options);
       return recv_createScanner();
     }
 
-    public void send_createScanner(ByteBuffer login, String tableName, ScanOptions options) throws org.apache.thrift.TException
+    public void send_createScanner(java.nio.ByteBuffer login, java.lang.String tableName, ScanOptions options) throws org.apache.thrift.TException
     {
       createScanner_args args = new createScanner_args();
       args.setLogin(login);
@@ -2466,7 +2439,7 @@
       sendBase("createScanner", args);
     }
 
-    public String recv_createScanner() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.lang.String recv_createScanner() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       createScanner_result result = new createScanner_result();
       receiveBase(result, "createScanner");
@@ -2485,13 +2458,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createScanner failed: unknown result");
     }
 
-    public boolean hasNext(String scanner) throws UnknownScanner, org.apache.thrift.TException
+    public boolean hasNext(java.lang.String scanner) throws UnknownScanner, org.apache.thrift.TException
     {
       send_hasNext(scanner);
       return recv_hasNext();
     }
 
-    public void send_hasNext(String scanner) throws org.apache.thrift.TException
+    public void send_hasNext(java.lang.String scanner) throws org.apache.thrift.TException
     {
       hasNext_args args = new hasNext_args();
       args.setScanner(scanner);
@@ -2511,13 +2484,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "hasNext failed: unknown result");
     }
 
-    public KeyValueAndPeek nextEntry(String scanner) throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException
+    public KeyValueAndPeek nextEntry(java.lang.String scanner) throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_nextEntry(scanner);
       return recv_nextEntry();
     }
 
-    public void send_nextEntry(String scanner) throws org.apache.thrift.TException
+    public void send_nextEntry(java.lang.String scanner) throws org.apache.thrift.TException
     {
       nextEntry_args args = new nextEntry_args();
       args.setScanner(scanner);
@@ -2543,13 +2516,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "nextEntry failed: unknown result");
     }
 
-    public ScanResult nextK(String scanner, int k) throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException
+    public ScanResult nextK(java.lang.String scanner, int k) throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_nextK(scanner, k);
       return recv_nextK();
     }
 
-    public void send_nextK(String scanner, int k) throws org.apache.thrift.TException
+    public void send_nextK(java.lang.String scanner, int k) throws org.apache.thrift.TException
     {
       nextK_args args = new nextK_args();
       args.setScanner(scanner);
@@ -2576,13 +2549,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "nextK failed: unknown result");
     }
 
-    public void closeScanner(String scanner) throws UnknownScanner, org.apache.thrift.TException
+    public void closeScanner(java.lang.String scanner) throws UnknownScanner, org.apache.thrift.TException
     {
       send_closeScanner(scanner);
       recv_closeScanner();
     }
 
-    public void send_closeScanner(String scanner) throws org.apache.thrift.TException
+    public void send_closeScanner(java.lang.String scanner) throws org.apache.thrift.TException
     {
       closeScanner_args args = new closeScanner_args();
       args.setScanner(scanner);
@@ -2599,13 +2572,13 @@
       return;
     }
 
-    public void updateAndFlush(ByteBuffer login, String tableName, Map<ByteBuffer,List<ColumnUpdate>> cells) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, MutationsRejectedException, org.apache.thrift.TException
+    public void updateAndFlush(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, MutationsRejectedException, org.apache.thrift.TException
     {
       send_updateAndFlush(login, tableName, cells);
       recv_updateAndFlush();
     }
 
-    public void send_updateAndFlush(ByteBuffer login, String tableName, Map<ByteBuffer,List<ColumnUpdate>> cells) throws org.apache.thrift.TException
+    public void send_updateAndFlush(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) throws org.apache.thrift.TException
     {
       updateAndFlush_args args = new updateAndFlush_args();
       args.setLogin(login);
@@ -2633,13 +2606,13 @@
       return;
     }
 
-    public String createWriter(ByteBuffer login, String tableName, WriterOptions opts) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.lang.String createWriter(java.nio.ByteBuffer login, java.lang.String tableName, WriterOptions opts) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_createWriter(login, tableName, opts);
       return recv_createWriter();
     }
 
-    public void send_createWriter(ByteBuffer login, String tableName, WriterOptions opts) throws org.apache.thrift.TException
+    public void send_createWriter(java.nio.ByteBuffer login, java.lang.String tableName, WriterOptions opts) throws org.apache.thrift.TException
     {
       createWriter_args args = new createWriter_args();
       args.setLogin(login);
@@ -2648,7 +2621,7 @@
       sendBase("createWriter", args);
     }
 
-    public String recv_createWriter() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.lang.String recv_createWriter() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       createWriter_result result = new createWriter_result();
       receiveBase(result, "createWriter");
@@ -2667,12 +2640,12 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createWriter failed: unknown result");
     }
 
-    public void update(String writer, Map<ByteBuffer,List<ColumnUpdate>> cells) throws org.apache.thrift.TException
+    public void update(java.lang.String writer, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) throws org.apache.thrift.TException
     {
       send_update(writer, cells);
     }
 
-    public void send_update(String writer, Map<ByteBuffer,List<ColumnUpdate>> cells) throws org.apache.thrift.TException
+    public void send_update(java.lang.String writer, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) throws org.apache.thrift.TException
     {
       update_args args = new update_args();
       args.setWriter(writer);
@@ -2680,13 +2653,13 @@
       sendBaseOneway("update", args);
     }
 
-    public void flush(String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException
+    public void flush(java.lang.String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException
     {
       send_flush(writer);
       recv_flush();
     }
 
-    public void send_flush(String writer) throws org.apache.thrift.TException
+    public void send_flush(java.lang.String writer) throws org.apache.thrift.TException
     {
       flush_args args = new flush_args();
       args.setWriter(writer);
@@ -2706,13 +2679,13 @@
       return;
     }
 
-    public void closeWriter(String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException
+    public void closeWriter(java.lang.String writer) throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException
     {
       send_closeWriter(writer);
       recv_closeWriter();
     }
 
-    public void send_closeWriter(String writer) throws org.apache.thrift.TException
+    public void send_closeWriter(java.lang.String writer) throws org.apache.thrift.TException
     {
       closeWriter_args args = new closeWriter_args();
       args.setWriter(writer);
@@ -2732,13 +2705,13 @@
       return;
     }
 
-    public ConditionalStatus updateRowConditionally(ByteBuffer login, String tableName, ByteBuffer row, ConditionalUpdates updates) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public ConditionalStatus updateRowConditionally(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer row, ConditionalUpdates updates) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_updateRowConditionally(login, tableName, row, updates);
       return recv_updateRowConditionally();
     }
 
-    public void send_updateRowConditionally(ByteBuffer login, String tableName, ByteBuffer row, ConditionalUpdates updates) throws org.apache.thrift.TException
+    public void send_updateRowConditionally(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer row, ConditionalUpdates updates) throws org.apache.thrift.TException
     {
       updateRowConditionally_args args = new updateRowConditionally_args();
       args.setLogin(login);
@@ -2767,13 +2740,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateRowConditionally failed: unknown result");
     }
 
-    public String createConditionalWriter(ByteBuffer login, String tableName, ConditionalWriterOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.lang.String createConditionalWriter(java.nio.ByteBuffer login, java.lang.String tableName, ConditionalWriterOptions options) throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       send_createConditionalWriter(login, tableName, options);
       return recv_createConditionalWriter();
     }
 
-    public void send_createConditionalWriter(ByteBuffer login, String tableName, ConditionalWriterOptions options) throws org.apache.thrift.TException
+    public void send_createConditionalWriter(java.nio.ByteBuffer login, java.lang.String tableName, ConditionalWriterOptions options) throws org.apache.thrift.TException
     {
       createConditionalWriter_args args = new createConditionalWriter_args();
       args.setLogin(login);
@@ -2782,7 +2755,7 @@
       sendBase("createConditionalWriter", args);
     }
 
-    public String recv_createConditionalWriter() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
+    public java.lang.String recv_createConditionalWriter() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException
     {
       createConditionalWriter_result result = new createConditionalWriter_result();
       receiveBase(result, "createConditionalWriter");
@@ -2801,13 +2774,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createConditionalWriter failed: unknown result");
     }
 
-    public Map<ByteBuffer,ConditionalStatus> updateRowsConditionally(String conditionalWriter, Map<ByteBuffer,ConditionalUpdates> updates) throws UnknownWriter, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.Map<java.nio.ByteBuffer,ConditionalStatus> updateRowsConditionally(java.lang.String conditionalWriter, java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates) throws UnknownWriter, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       send_updateRowsConditionally(conditionalWriter, updates);
       return recv_updateRowsConditionally();
     }
 
-    public void send_updateRowsConditionally(String conditionalWriter, Map<ByteBuffer,ConditionalUpdates> updates) throws org.apache.thrift.TException
+    public void send_updateRowsConditionally(java.lang.String conditionalWriter, java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates) throws org.apache.thrift.TException
     {
       updateRowsConditionally_args args = new updateRowsConditionally_args();
       args.setConditionalWriter(conditionalWriter);
@@ -2815,7 +2788,7 @@
       sendBase("updateRowsConditionally", args);
     }
 
-    public Map<ByteBuffer,ConditionalStatus> recv_updateRowsConditionally() throws UnknownWriter, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
+    public java.util.Map<java.nio.ByteBuffer,ConditionalStatus> recv_updateRowsConditionally() throws UnknownWriter, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       updateRowsConditionally_result result = new updateRowsConditionally_result();
       receiveBase(result, "updateRowsConditionally");
@@ -2834,13 +2807,13 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateRowsConditionally failed: unknown result");
     }
 
-    public void closeConditionalWriter(String conditionalWriter) throws org.apache.thrift.TException
+    public void closeConditionalWriter(java.lang.String conditionalWriter) throws org.apache.thrift.TException
     {
       send_closeConditionalWriter(conditionalWriter);
       recv_closeConditionalWriter();
     }
 
-    public void send_closeConditionalWriter(String conditionalWriter) throws org.apache.thrift.TException
+    public void send_closeConditionalWriter(java.lang.String conditionalWriter) throws org.apache.thrift.TException
     {
       closeConditionalWriter_args args = new closeConditionalWriter_args();
       args.setConditionalWriter(conditionalWriter);
@@ -2854,13 +2827,13 @@
       return;
     }
 
-    public Range getRowRange(ByteBuffer row) throws org.apache.thrift.TException
+    public Range getRowRange(java.nio.ByteBuffer row) throws org.apache.thrift.TException
     {
       send_getRowRange(row);
       return recv_getRowRange();
     }
 
-    public void send_getRowRange(ByteBuffer row) throws org.apache.thrift.TException
+    public void send_getRowRange(java.nio.ByteBuffer row) throws org.apache.thrift.TException
     {
       getRowRange_args args = new getRowRange_args();
       args.setRow(row);
@@ -2901,7 +2874,7 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getFollowing failed: unknown result");
     }
 
-    public String systemNamespace() throws org.apache.thrift.TException
+    public java.lang.String systemNamespace() throws org.apache.thrift.TException
     {
       send_systemNamespace();
       return recv_systemNamespace();
@@ -2913,7 +2886,7 @@
       sendBase("systemNamespace", args);
     }
 
-    public String recv_systemNamespace() throws org.apache.thrift.TException
+    public java.lang.String recv_systemNamespace() throws org.apache.thrift.TException
     {
       systemNamespace_result result = new systemNamespace_result();
       receiveBase(result, "systemNamespace");
@@ -2923,7 +2896,7 @@
       throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "systemNamespace failed: unknown result");
     }
 
-    public String defaultNamespace() throws org.apache.thrift.TException
+    public java.lang.String defaultNamespace() throws org.apache.thrift.TException
     {
       send_defaultNamespace();
       return recv_defaultNamespace();
@@ -2935,7 +2908,7 @@
       sendBase("defaultNamespace", args);
     }
 
-    public String recv_defaultNamespace() throws org.apache.thrift.TException
+    public java.lang.String recv_defaultNamespace() throws org.apache.thrift.TException
     {
       defaultNamespace_result result = new defaultNamespace_result();
       receiveBase(result, "defaultNamespace");
@@ -2945,20 +2918,20 @@
       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
+    public java.util.List<java.lang.String> listNamespaces(java.nio.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
+    public void send_listNamespaces(java.nio.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
+    public java.util.List<java.lang.String> recv_listNamespaces() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       listNamespaces_result result = new listNamespaces_result();
       receiveBase(result, "listNamespaces");
@@ -2974,13 +2947,13 @@
       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
+    public boolean namespaceExists(java.nio.ByteBuffer login, java.lang.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
+    public void send_namespaceExists(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
     {
       namespaceExists_args args = new namespaceExists_args();
       args.setLogin(login);
@@ -3004,13 +2977,13 @@
       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
+    public void createNamespace(java.nio.ByteBuffer login, java.lang.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
+    public void send_createNamespace(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
     {
       createNamespace_args args = new createNamespace_args();
       args.setLogin(login);
@@ -3034,13 +3007,13 @@
       return;
     }
 
-    public void deleteNamespace(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceNotEmptyException, org.apache.thrift.TException
+    public void deleteNamespace(java.nio.ByteBuffer login, java.lang.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
+    public void send_deleteNamespace(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
     {
       deleteNamespace_args args = new deleteNamespace_args();
       args.setLogin(login);
@@ -3067,13 +3040,13 @@
       return;
     }
 
-    public void renameNamespace(ByteBuffer login, String oldNamespaceName, String newNamespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceExistsException, org.apache.thrift.TException
+    public void renameNamespace(java.nio.ByteBuffer login, java.lang.String oldNamespaceName, java.lang.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
+    public void send_renameNamespace(java.nio.ByteBuffer login, java.lang.String oldNamespaceName, java.lang.String newNamespaceName) throws org.apache.thrift.TException
     {
       renameNamespace_args args = new renameNamespace_args();
       args.setLogin(login);
@@ -3101,13 +3074,13 @@
       return;
     }
 
-    public void setNamespaceProperty(ByteBuffer login, String namespaceName, String property, String value) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    public void setNamespaceProperty(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property, java.lang.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
+    public void send_setNamespaceProperty(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property, java.lang.String value) throws org.apache.thrift.TException
     {
       setNamespaceProperty_args args = new setNamespaceProperty_args();
       args.setLogin(login);
@@ -3133,13 +3106,13 @@
       return;
     }
 
-    public void removeNamespaceProperty(ByteBuffer login, String namespaceName, String property) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    public void removeNamespaceProperty(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.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
+    public void send_removeNamespaceProperty(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property) throws org.apache.thrift.TException
     {
       removeNamespaceProperty_args args = new removeNamespaceProperty_args();
       args.setLogin(login);
@@ -3164,13 +3137,13 @@
       return;
     }
 
-    public Map<String,String> getNamespaceProperties(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.String> getNamespaceProperties(java.nio.ByteBuffer login, java.lang.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
+    public void send_getNamespaceProperties(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
     {
       getNamespaceProperties_args args = new getNamespaceProperties_args();
       args.setLogin(login);
@@ -3178,7 +3151,7 @@
       sendBase("getNamespaceProperties", args);
     }
 
-    public Map<String,String> recv_getNamespaceProperties() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.String> recv_getNamespaceProperties() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
     {
       getNamespaceProperties_result result = new getNamespaceProperties_result();
       receiveBase(result, "getNamespaceProperties");
@@ -3197,20 +3170,20 @@
       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
+    public java.util.Map<java.lang.String,java.lang.String> namespaceIdMap(java.nio.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
+    public void send_namespaceIdMap(java.nio.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
+    public java.util.Map<java.lang.String,java.lang.String> recv_namespaceIdMap() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException
     {
       namespaceIdMap_result result = new namespaceIdMap_result();
       receiveBase(result, "namespaceIdMap");
@@ -3226,13 +3199,13 @@
       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
+    public void attachNamespaceIterator(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.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
+    public void send_attachNamespaceIterator(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.Set<IteratorScope> scopes) throws org.apache.thrift.TException
     {
       attachNamespaceIterator_args args = new attachNamespaceIterator_args();
       args.setLogin(login);
@@ -3258,13 +3231,13 @@
       return;
     }
 
-    public void removeNamespaceIterator(ByteBuffer login, String namespaceName, String name, Set<IteratorScope> scopes) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    public void removeNamespaceIterator(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, java.util.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
+    public void send_removeNamespaceIterator(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, java.util.Set<IteratorScope> scopes) throws org.apache.thrift.TException
     {
       removeNamespaceIterator_args args = new removeNamespaceIterator_args();
       args.setLogin(login);
@@ -3290,13 +3263,13 @@
       return;
     }
 
-    public IteratorSetting getNamespaceIteratorSetting(ByteBuffer login, String namespaceName, String name, IteratorScope scope) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    public IteratorSetting getNamespaceIteratorSetting(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.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
+    public void send_getNamespaceIteratorSetting(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, IteratorScope scope) throws org.apache.thrift.TException
     {
       getNamespaceIteratorSetting_args args = new getNamespaceIteratorSetting_args();
       args.setLogin(login);
@@ -3325,13 +3298,13 @@
       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
+    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> listNamespaceIterators(java.nio.ByteBuffer login, java.lang.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
+    public void send_listNamespaceIterators(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
     {
       listNamespaceIterators_args args = new listNamespaceIterators_args();
       args.setLogin(login);
@@ -3339,7 +3312,7 @@
       sendBase("listNamespaceIterators", args);
     }
 
-    public Map<String,Set<IteratorScope>> recv_listNamespaceIterators() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> recv_listNamespaceIterators() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
     {
       listNamespaceIterators_result result = new listNamespaceIterators_result();
       receiveBase(result, "listNamespaceIterators");
@@ -3358,13 +3331,13 @@
       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
+    public void checkNamespaceIteratorConflicts(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.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
+    public void send_checkNamespaceIteratorConflicts(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.Set<IteratorScope> scopes) throws org.apache.thrift.TException
     {
       checkNamespaceIteratorConflicts_args args = new checkNamespaceIteratorConflicts_args();
       args.setLogin(login);
@@ -3390,13 +3363,13 @@
       return;
     }
 
-    public int addNamespaceConstraint(ByteBuffer login, String namespaceName, String constraintClassName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    public int addNamespaceConstraint(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.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
+    public void send_addNamespaceConstraint(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String constraintClassName) throws org.apache.thrift.TException
     {
       addNamespaceConstraint_args args = new addNamespaceConstraint_args();
       args.setLogin(login);
@@ -3424,13 +3397,13 @@
       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
+    public void removeNamespaceConstraint(java.nio.ByteBuffer login, java.lang.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
+    public void send_removeNamespaceConstraint(java.nio.ByteBuffer login, java.lang.String namespaceName, int id) throws org.apache.thrift.TException
     {
       removeNamespaceConstraint_args args = new removeNamespaceConstraint_args();
       args.setLogin(login);
@@ -3455,13 +3428,13 @@
       return;
     }
 
-    public Map<String,Integer> listNamespaceConstraints(ByteBuffer login, String namespaceName) throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.Integer> listNamespaceConstraints(java.nio.ByteBuffer login, java.lang.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
+    public void send_listNamespaceConstraints(java.nio.ByteBuffer login, java.lang.String namespaceName) throws org.apache.thrift.TException
     {
       listNamespaceConstraints_args args = new listNamespaceConstraints_args();
       args.setLogin(login);
@@ -3469,7 +3442,7 @@
       sendBase("listNamespaceConstraints", args);
     }
 
-    public Map<String,Integer> recv_listNamespaceConstraints() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
+    public java.util.Map<java.lang.String,java.lang.Integer> recv_listNamespaceConstraints() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException
     {
       listNamespaceConstraints_result result = new listNamespaceConstraints_result();
       receiveBase(result, "listNamespaceConstraints");
@@ -3488,13 +3461,13 @@
       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
+    public boolean testNamespaceClassLoad(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String className, java.lang.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
+    public void send_testNamespaceClassLoad(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String className, java.lang.String asTypeName) throws org.apache.thrift.TException
     {
       testNamespaceClassLoad_args args = new testNamespaceClassLoad_args();
       args.setLogin(login);
@@ -3541,17 +3514,17 @@
       super(protocolFactory, clientManager, transport);
     }
 
-    public void login(String principal, Map<String,String> loginProperties, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void login(java.lang.String principal, java.util.Map<java.lang.String,java.lang.String> loginProperties, org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       login_call method_call = new login_call(principal, loginProperties, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class login_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String principal;
-      private Map<String,String> loginProperties;
-      public login_call(String principal, Map<String,String> loginProperties, 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 {
+    public static class login_call extends org.apache.thrift.async.TAsyncMethodCall<java.nio.ByteBuffer> {
+      private java.lang.String principal;
+      private java.util.Map<java.lang.String,java.lang.String> loginProperties;
+      public login_call(java.lang.String principal, java.util.Map<java.lang.String,java.lang.String> loginProperties, org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer> 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.principal = principal;
         this.loginProperties = loginProperties;
@@ -3566,9 +3539,9 @@
         prot.writeMessageEnd();
       }
 
-      public ByteBuffer getResult() throws AccumuloSecurityException, org.apache.thrift.TException {
+      public java.nio.ByteBuffer getResult() throws AccumuloSecurityException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -3576,18 +3549,18 @@
       }
     }
 
-    public void addConstraint(ByteBuffer login, String tableName, String constraintClassName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void addConstraint(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String constraintClassName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       addConstraint_call method_call = new addConstraint_call(login, tableName, constraintClassName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class addConstraint_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private String constraintClassName;
-      public addConstraint_call(ByteBuffer login, String tableName, 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 {
+    public static class addConstraint_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Integer> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.lang.String constraintClassName;
+      public addConstraint_call(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String constraintClassName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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.tableName = tableName;
@@ -3604,9 +3577,9 @@
         prot.writeMessageEnd();
       }
 
-      public int getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.lang.Integer getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -3614,18 +3587,18 @@
       }
     }
 
-    public void addSplits(ByteBuffer login, String tableName, Set<ByteBuffer> splits, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void addSplits(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> splits, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       addSplits_call method_call = new addSplits_call(login, tableName, splits, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class addSplits_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private Set<ByteBuffer> splits;
-      public addSplits_call(ByteBuffer login, String tableName, Set<ByteBuffer> splits, 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 {
+    public static class addSplits_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.util.Set<java.nio.ByteBuffer> splits;
+      public addSplits_call(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> splits, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -3642,29 +3615,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_addSplits();
+        return null;
       }
     }
 
-    public void attachIterator(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void attachIterator(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       attachIterator_call method_call = new attachIterator_call(login, tableName, setting, scopes, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class attachIterator_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class attachIterator_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private IteratorSetting setting;
-      private Set<IteratorScope> scopes;
-      public attachIterator_call(ByteBuffer login, String tableName, 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 {
+      private java.util.Set<IteratorScope> scopes;
+      public attachIterator_call(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -3683,29 +3656,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_attachIterator();
+        return null;
       }
     }
 
-    public void checkIteratorConflicts(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void checkIteratorConflicts(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       checkIteratorConflicts_call method_call = new checkIteratorConflicts_call(login, tableName, setting, scopes, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class checkIteratorConflicts_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class checkIteratorConflicts_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private IteratorSetting setting;
-      private Set<IteratorScope> scopes;
-      public checkIteratorConflicts_call(ByteBuffer login, String tableName, 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 {
+      private java.util.Set<IteratorScope> scopes;
+      public checkIteratorConflicts_call(java.nio.ByteBuffer login, java.lang.String tableName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -3724,27 +3697,27 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloSecurityException, AccumuloException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_checkIteratorConflicts();
+        return null;
       }
     }
 
-    public void clearLocatorCache(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void clearLocatorCache(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       clearLocatorCache_call method_call = new clearLocatorCache_call(login, tableName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class clearLocatorCache_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      public clearLocatorCache_call(ByteBuffer login, String tableName, 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 {
+    public static class clearLocatorCache_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      public clearLocatorCache_call(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -3759,31 +3732,31 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_clearLocatorCache();
+        return null;
       }
     }
 
-    public void cloneTable(ByteBuffer login, String tableName, String newTableName, boolean flush, Map<String,String> propertiesToSet, Set<String> propertiesToExclude, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void cloneTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String newTableName, boolean flush, java.util.Map<java.lang.String,java.lang.String> propertiesToSet, java.util.Set<java.lang.String> propertiesToExclude, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       cloneTable_call method_call = new cloneTable_call(login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class cloneTable_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private String newTableName;
+    public static class cloneTable_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.lang.String newTableName;
       private boolean flush;
-      private Map<String,String> propertiesToSet;
-      private Set<String> propertiesToExclude;
-      public cloneTable_call(ByteBuffer login, String tableName, String newTableName, boolean flush, Map<String,String> propertiesToSet, Set<String> propertiesToExclude, 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 {
+      private java.util.Map<java.lang.String,java.lang.String> propertiesToSet;
+      private java.util.Set<java.lang.String> propertiesToExclude;
+      public cloneTable_call(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String newTableName, boolean flush, java.util.Map<java.lang.String,java.lang.String> propertiesToSet, java.util.Set<java.lang.String> propertiesToExclude, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -3806,33 +3779,33 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_cloneTable();
+        return null;
       }
     }
 
-    public void compactTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void compactTable(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, java.util.List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       compactTable_call method_call = new compactTable_call(login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class compactTable_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private ByteBuffer startRow;
-      private ByteBuffer endRow;
-      private List<IteratorSetting> iterators;
+    public static class compactTable_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.nio.ByteBuffer startRow;
+      private java.nio.ByteBuffer endRow;
+      private java.util.List<IteratorSetting> iterators;
       private boolean flush;
       private boolean wait;
       private CompactionStrategyConfig compactionStrategy;
-      public compactTable_call(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy, 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 {
+      public compactTable_call(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, java.util.List<IteratorSetting> iterators, boolean flush, boolean wait, CompactionStrategyConfig compactionStrategy, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -3859,27 +3832,27 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_compactTable();
+        return null;
       }
     }
 
-    public void cancelCompaction(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void cancelCompaction(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       cancelCompaction_call method_call = new cancelCompaction_call(login, tableName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class cancelCompaction_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      public cancelCompaction_call(ByteBuffer login, String tableName, 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 {
+    public static class cancelCompaction_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      public cancelCompaction_call(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -3894,29 +3867,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloSecurityException, TableNotFoundException, AccumuloException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_cancelCompaction();
+        return null;
       }
     }
 
-    public void createTable(ByteBuffer login, String tableName, boolean versioningIter, TimeType type, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void createTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean versioningIter, TimeType type, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       createTable_call method_call = new createTable_call(login, tableName, versioningIter, type, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class createTable_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class createTable_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private boolean versioningIter;
       private TimeType type;
-      public createTable_call(ByteBuffer login, String tableName, boolean versioningIter, TimeType type, 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 {
+      public createTable_call(java.nio.ByteBuffer login, java.lang.String tableName, boolean versioningIter, TimeType type, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -3935,27 +3908,27 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableExistsException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableExistsException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_createTable();
+        return null;
       }
     }
 
-    public void deleteTable(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void deleteTable(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       deleteTable_call method_call = new deleteTable_call(login, tableName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class deleteTable_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      public deleteTable_call(ByteBuffer login, String tableName, 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 {
+    public static class deleteTable_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      public deleteTable_call(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -3970,29 +3943,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_deleteTable();
+        return null;
       }
     }
 
-    public void deleteRows(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void deleteRows(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       deleteRows_call method_call = new deleteRows_call(login, tableName, startRow, endRow, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class deleteRows_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private ByteBuffer startRow;
-      private ByteBuffer endRow;
-      public deleteRows_call(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, 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 {
+    public static class deleteRows_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.nio.ByteBuffer startRow;
+      private java.nio.ByteBuffer endRow;
+      public deleteRows_call(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4011,28 +3984,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_deleteRows();
+        return null;
       }
     }
 
-    public void exportTable(ByteBuffer login, String tableName, String exportDir, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void exportTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String exportDir, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       exportTable_call method_call = new exportTable_call(login, tableName, exportDir, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class exportTable_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private String exportDir;
-      public exportTable_call(ByteBuffer login, String tableName, String exportDir, 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 {
+    public static class exportTable_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.lang.String exportDir;
+      public exportTable_call(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String exportDir, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4049,30 +4022,30 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_exportTable();
+        return null;
       }
     }
 
-    public void flushTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, boolean wait, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void flushTable(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, boolean wait, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       flushTable_call method_call = new flushTable_call(login, tableName, startRow, endRow, wait, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class flushTable_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private ByteBuffer startRow;
-      private ByteBuffer endRow;
+    public static class flushTable_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.nio.ByteBuffer startRow;
+      private java.nio.ByteBuffer endRow;
       private boolean wait;
-      public flushTable_call(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, boolean wait, 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 {
+      public flushTable_call(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, boolean wait, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4093,27 +4066,27 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_flushTable();
+        return null;
       }
     }
 
-    public void getDiskUsage(ByteBuffer login, Set<String> tables, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getDiskUsage(java.nio.ByteBuffer login, java.util.Set<java.lang.String> tables, org.apache.thrift.async.AsyncMethodCallback<java.util.List<DiskUsage>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getDiskUsage_call method_call = new getDiskUsage_call(login, tables, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getDiskUsage_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private Set<String> tables;
-      public getDiskUsage_call(ByteBuffer login, Set<String> tables, 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 {
+    public static class getDiskUsage_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<DiskUsage>> {
+      private java.nio.ByteBuffer login;
+      private java.util.Set<java.lang.String> tables;
+      public getDiskUsage_call(java.nio.ByteBuffer login, java.util.Set<java.lang.String> tables, org.apache.thrift.async.AsyncMethodCallback<java.util.List<DiskUsage>> 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.tables = tables;
@@ -4128,9 +4101,9 @@
         prot.writeMessageEnd();
       }
 
-      public List<DiskUsage> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.util.List<DiskUsage> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4138,17 +4111,17 @@
       }
     }
 
-    public void getLocalityGroups(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getLocalityGroups(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<java.lang.String>>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getLocalityGroups_call method_call = new getLocalityGroups_call(login, tableName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getLocalityGroups_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      public getLocalityGroups_call(ByteBuffer login, String tableName, 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 {
+    public static class getLocalityGroups_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.util.Set<java.lang.String>>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      public getLocalityGroups_call(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<java.lang.String>>> 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.tableName = tableName;
@@ -4163,9 +4136,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,Set<String>> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4173,19 +4146,19 @@
       }
     }
 
-    public void getIteratorSetting(ByteBuffer login, String tableName, String iteratorName, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getIteratorSetting(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iteratorName, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getIteratorSetting_call method_call = new getIteratorSetting_call(login, tableName, iteratorName, scope, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getIteratorSetting_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private String iteratorName;
+    public static class getIteratorSetting_call extends org.apache.thrift.async.TAsyncMethodCall<IteratorSetting> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.lang.String iteratorName;
       private IteratorScope scope;
-      public getIteratorSetting_call(ByteBuffer login, String tableName, String iteratorName, 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 {
+      public getIteratorSetting_call(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iteratorName, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> 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.tableName = tableName;
@@ -4206,7 +4179,7 @@
 
       public IteratorSetting getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4214,22 +4187,22 @@
       }
     }
 
-    public void getMaxRow(ByteBuffer login, String tableName, Set<ByteBuffer> auths, ByteBuffer startRow, boolean startInclusive, ByteBuffer endRow, boolean endInclusive, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getMaxRow(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> auths, java.nio.ByteBuffer startRow, boolean startInclusive, java.nio.ByteBuffer endRow, boolean endInclusive, org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getMaxRow_call method_call = new getMaxRow_call(login, tableName, auths, startRow, startInclusive, endRow, endInclusive, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getMaxRow_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private Set<ByteBuffer> auths;
-      private ByteBuffer startRow;
+    public static class getMaxRow_call extends org.apache.thrift.async.TAsyncMethodCall<java.nio.ByteBuffer> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.util.Set<java.nio.ByteBuffer> auths;
+      private java.nio.ByteBuffer startRow;
       private boolean startInclusive;
-      private ByteBuffer endRow;
+      private java.nio.ByteBuffer endRow;
       private boolean endInclusive;
-      public getMaxRow_call(ByteBuffer login, String tableName, Set<ByteBuffer> auths, ByteBuffer startRow, boolean startInclusive, ByteBuffer endRow, boolean endInclusive, 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 {
+      public getMaxRow_call(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Set<java.nio.ByteBuffer> auths, java.nio.ByteBuffer startRow, boolean startInclusive, java.nio.ByteBuffer endRow, boolean endInclusive, org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer> 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.tableName = tableName;
@@ -4254,9 +4227,9 @@
         prot.writeMessageEnd();
       }
 
-      public ByteBuffer getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.nio.ByteBuffer getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4264,17 +4237,17 @@
       }
     }
 
-    public void getTableProperties(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getTableProperties(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getTableProperties_call method_call = new getTableProperties_call(login, tableName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getTableProperties_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      public getTableProperties_call(ByteBuffer login, String tableName, 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 {
+    public static class getTableProperties_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.lang.String>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      public getTableProperties_call(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> 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.tableName = tableName;
@@ -4289,9 +4262,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,String> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.lang.String> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4299,20 +4272,20 @@
       }
     }
 
-    public void importDirectory(ByteBuffer login, String tableName, String importDir, String failureDir, boolean setTime, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void importDirectory(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir, java.lang.String failureDir, boolean setTime, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       importDirectory_call method_call = new importDirectory_call(login, tableName, importDir, failureDir, setTime, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class importDirectory_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private String importDir;
-      private String failureDir;
+    public static class importDirectory_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.lang.String importDir;
+      private java.lang.String failureDir;
       private boolean setTime;
-      public importDirectory_call(ByteBuffer login, String tableName, String importDir, String failureDir, boolean setTime, 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 {
+      public importDirectory_call(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir, java.lang.String failureDir, boolean setTime, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4333,28 +4306,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws TableNotFoundException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public Void getResult() throws TableNotFoundException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_importDirectory();
+        return null;
       }
     }
 
-    public void importTable(ByteBuffer login, String tableName, String importDir, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void importTable(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       importTable_call method_call = new importTable_call(login, tableName, importDir, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class importTable_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private String importDir;
-      public importTable_call(ByteBuffer login, String tableName, String importDir, 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 {
+    public static class importTable_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.lang.String importDir;
+      public importTable_call(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String importDir, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4371,28 +4344,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws TableExistsException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public Void getResult() throws TableExistsException, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_importTable();
+        return null;
       }
     }
 
-    public void listSplits(ByteBuffer login, String tableName, int maxSplits, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void listSplits(java.nio.ByteBuffer login, java.lang.String tableName, int maxSplits, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       listSplits_call method_call = new listSplits_call(login, tableName, maxSplits, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class listSplits_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class listSplits_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<java.nio.ByteBuffer>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private int maxSplits;
-      public listSplits_call(ByteBuffer login, String tableName, int maxSplits, 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 {
+      public listSplits_call(java.nio.ByteBuffer login, java.lang.String tableName, int maxSplits, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>> 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.tableName = tableName;
@@ -4409,9 +4382,9 @@
         prot.writeMessageEnd();
       }
 
-      public List<ByteBuffer> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.util.List<java.nio.ByteBuffer> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4419,16 +4392,16 @@
       }
     }
 
-    public void listTables(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void listTables(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       listTables_call method_call = new listTables_call(login, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class listTables_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      public listTables_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 {
+    public static class listTables_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Set<java.lang.String>> {
+      private java.nio.ByteBuffer login;
+      public listTables_call(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> 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;
       }
@@ -4441,9 +4414,9 @@
         prot.writeMessageEnd();
       }
 
-      public Set<String> getResult() throws org.apache.thrift.TException {
+      public java.util.Set<java.lang.String> getResult() throws org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4451,17 +4424,17 @@
       }
     }
 
-    public void listIterators(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void listIterators(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       listIterators_call method_call = new listIterators_call(login, tableName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class listIterators_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      public listIterators_call(ByteBuffer login, String tableName, 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 {
+    public static class listIterators_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      public listIterators_call(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> 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.tableName = tableName;
@@ -4476,9 +4449,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,Set<IteratorScope>> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4486,17 +4459,17 @@
       }
     }
 
-    public void listConstraints(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void listConstraints(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       listConstraints_call method_call = new listConstraints_call(login, tableName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class listConstraints_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      public listConstraints_call(ByteBuffer login, String tableName, 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 {
+    public static class listConstraints_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.lang.Integer>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      public listConstraints_call(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>> 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.tableName = tableName;
@@ -4511,9 +4484,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,Integer> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.lang.Integer> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4521,19 +4494,19 @@
       }
     }
 
-    public void mergeTablets(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void mergeTablets(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       mergeTablets_call method_call = new mergeTablets_call(login, tableName, startRow, endRow, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class mergeTablets_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private ByteBuffer startRow;
-      private ByteBuffer endRow;
-      public mergeTablets_call(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, 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 {
+    public static class mergeTablets_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.nio.ByteBuffer startRow;
+      private java.nio.ByteBuffer endRow;
+      public mergeTablets_call(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer startRow, java.nio.ByteBuffer endRow, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4552,28 +4525,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_mergeTablets();
+        return null;
       }
     }
 
-    public void offlineTable(ByteBuffer login, String tableName, boolean wait, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void offlineTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       offlineTable_call method_call = new offlineTable_call(login, tableName, wait, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class offlineTable_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class offlineTable_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private boolean wait;
-      public offlineTable_call(ByteBuffer login, String tableName, boolean wait, 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 {
+      public offlineTable_call(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4590,28 +4563,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_offlineTable();
+        return null;
       }
     }
 
-    public void onlineTable(ByteBuffer login, String tableName, boolean wait, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void onlineTable(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       onlineTable_call method_call = new onlineTable_call(login, tableName, wait, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class onlineTable_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class onlineTable_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private boolean wait;
-      public onlineTable_call(ByteBuffer login, String tableName, boolean wait, 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 {
+      public onlineTable_call(java.nio.ByteBuffer login, java.lang.String tableName, boolean wait, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4628,28 +4601,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_onlineTable();
+        return null;
       }
     }
 
-    public void removeConstraint(ByteBuffer login, String tableName, int constraint, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void removeConstraint(java.nio.ByteBuffer login, java.lang.String tableName, int constraint, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       removeConstraint_call method_call = new removeConstraint_call(login, tableName, constraint, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class removeConstraint_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class removeConstraint_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private int constraint;
-      public removeConstraint_call(ByteBuffer login, String tableName, int constraint, 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 {
+      public removeConstraint_call(java.nio.ByteBuffer login, java.lang.String tableName, int constraint, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4666,29 +4639,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_removeConstraint();
+        return null;
       }
     }
 
-    public void removeIterator(ByteBuffer login, String tableName, String iterName, Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void removeIterator(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iterName, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       removeIterator_call method_call = new removeIterator_call(login, tableName, iterName, scopes, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class removeIterator_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private String iterName;
-      private Set<IteratorScope> scopes;
-      public removeIterator_call(ByteBuffer login, String tableName, String iterName, 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 {
+    public static class removeIterator_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.lang.String iterName;
+      private java.util.Set<IteratorScope> scopes;
+      public removeIterator_call(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String iterName, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4707,28 +4680,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_removeIterator();
+        return null;
       }
     }
 
-    public void removeTableProperty(ByteBuffer login, String tableName, String property, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void removeTableProperty(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       removeTableProperty_call method_call = new removeTableProperty_call(login, tableName, property, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class removeTableProperty_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private String property;
-      public removeTableProperty_call(ByteBuffer login, String tableName, 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 {
+    public static class removeTableProperty_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.lang.String property;
+      public removeTableProperty_call(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4745,28 +4718,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_removeTableProperty();
+        return null;
       }
     }
 
-    public void renameTable(ByteBuffer login, String oldTableName, String newTableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void renameTable(java.nio.ByteBuffer login, java.lang.String oldTableName, java.lang.String newTableName, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       renameTable_call method_call = new renameTable_call(login, oldTableName, newTableName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class renameTable_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String oldTableName;
-      private String newTableName;
-      public renameTable_call(ByteBuffer login, String oldTableName, String newTableName, 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 {
+    public static class renameTable_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String oldTableName;
+      private java.lang.String newTableName;
+      public renameTable_call(java.nio.ByteBuffer login, java.lang.String oldTableName, java.lang.String newTableName, org.apache.thrift.async.AsyncMethodCallback<Void> 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.oldTableName = oldTableName;
@@ -4783,28 +4756,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_renameTable();
+        return null;
       }
     }
 
-    public void setLocalityGroups(ByteBuffer login, String tableName, Map<String,Set<String>> groups, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void setLocalityGroups(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       setLocalityGroups_call method_call = new setLocalityGroups_call(login, tableName, groups, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class setLocalityGroups_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private Map<String,Set<String>> groups;
-      public setLocalityGroups_call(ByteBuffer login, String tableName, Map<String,Set<String>> groups, 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 {
+    public static class setLocalityGroups_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups;
+      public setLocalityGroups_call(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4821,29 +4794,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_setLocalityGroups();
+        return null;
       }
     }
 
-    public void setTableProperty(ByteBuffer login, String tableName, String property, String value, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void setTableProperty(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property, java.lang.String value, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       setTableProperty_call method_call = new setTableProperty_call(login, tableName, property, value, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class setTableProperty_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private String property;
-      private String value;
-      public setTableProperty_call(ByteBuffer login, String tableName, 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 {
+    public static class setTableProperty_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.lang.String property;
+      private java.lang.String value;
+      public setTableProperty_call(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String property, java.lang.String value, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -4862,29 +4835,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_setTableProperty();
+        return null;
       }
     }
 
-    public void splitRangeByTablets(ByteBuffer login, String tableName, Range range, int maxSplits, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void splitRangeByTablets(java.nio.ByteBuffer login, java.lang.String tableName, Range range, int maxSplits, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<Range>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       splitRangeByTablets_call method_call = new splitRangeByTablets_call(login, tableName, range, maxSplits, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class splitRangeByTablets_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class splitRangeByTablets_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Set<Range>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private Range range;
       private int maxSplits;
-      public splitRangeByTablets_call(ByteBuffer login, String tableName, Range range, int maxSplits, 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 {
+      public splitRangeByTablets_call(java.nio.ByteBuffer login, java.lang.String tableName, Range range, int maxSplits, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<Range>> 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.tableName = tableName;
@@ -4903,9 +4876,9 @@
         prot.writeMessageEnd();
       }
 
-      public Set<Range> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.util.Set<Range> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4913,17 +4886,17 @@
       }
     }
 
-    public void tableExists(ByteBuffer login, String tableName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void tableExists(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       tableExists_call method_call = new tableExists_call(login, tableName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class tableExists_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      public tableExists_call(ByteBuffer login, String tableName, 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 {
+    public static class tableExists_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      public tableExists_call(java.nio.ByteBuffer login, java.lang.String tableName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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.tableName = tableName;
@@ -4938,9 +4911,9 @@
         prot.writeMessageEnd();
       }
 
-      public boolean getResult() throws org.apache.thrift.TException {
+      public java.lang.Boolean getResult() throws org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4948,16 +4921,16 @@
       }
     }
 
-    public void tableIdMap(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void tableIdMap(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       tableIdMap_call method_call = new tableIdMap_call(login, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class tableIdMap_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      public tableIdMap_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 {
+    public static class tableIdMap_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.lang.String>> {
+      private java.nio.ByteBuffer login;
+      public tableIdMap_call(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> 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;
       }
@@ -4970,9 +4943,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,String> getResult() throws org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.lang.String> getResult() throws org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -4980,19 +4953,19 @@
       }
     }
 
-    public void testTableClassLoad(ByteBuffer login, String tableName, String className, String asTypeName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void testTableClassLoad(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String className, java.lang.String asTypeName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       testTableClassLoad_call method_call = new testTableClassLoad_call(login, tableName, className, asTypeName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class testTableClassLoad_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private String className;
-      private String asTypeName;
-      public testTableClassLoad_call(ByteBuffer login, String tableName, 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 {
+    public static class testTableClassLoad_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.lang.String className;
+      private java.lang.String asTypeName;
+      public testTableClassLoad_call(java.nio.ByteBuffer login, java.lang.String tableName, java.lang.String className, java.lang.String asTypeName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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.tableName = tableName;
@@ -5011,9 +4984,9 @@
         prot.writeMessageEnd();
       }
 
-      public boolean getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.lang.Boolean getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -5021,17 +4994,17 @@
       }
     }
 
-    public void pingTabletServer(ByteBuffer login, String tserver, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void pingTabletServer(java.nio.ByteBuffer login, java.lang.String tserver, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       pingTabletServer_call method_call = new pingTabletServer_call(login, tserver, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class pingTabletServer_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tserver;
-      public pingTabletServer_call(ByteBuffer login, String tserver, 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 {
+    public static class pingTabletServer_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tserver;
+      public pingTabletServer_call(java.nio.ByteBuffer login, java.lang.String tserver, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tserver = tserver;
@@ -5046,27 +5019,27 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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_pingTabletServer();
+        return null;
       }
     }
 
-    public void getActiveScans(ByteBuffer login, String tserver, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getActiveScans(java.nio.ByteBuffer login, java.lang.String tserver, org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveScan>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getActiveScans_call method_call = new getActiveScans_call(login, tserver, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getActiveScans_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tserver;
-      public getActiveScans_call(ByteBuffer login, String tserver, 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 {
+    public static class getActiveScans_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<ActiveScan>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tserver;
+      public getActiveScans_call(java.nio.ByteBuffer login, java.lang.String tserver, org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveScan>> 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.tserver = tserver;
@@ -5081,9 +5054,9 @@
         prot.writeMessageEnd();
       }
 
-      public List<ActiveScan> getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.util.List<ActiveScan> 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!");
+          throw new java.lang.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);
@@ -5091,17 +5064,17 @@
       }
     }
 
-    public void getActiveCompactions(ByteBuffer login, String tserver, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getActiveCompactions(java.nio.ByteBuffer login, java.lang.String tserver, org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveCompaction>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getActiveCompactions_call method_call = new getActiveCompactions_call(login, tserver, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getActiveCompactions_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tserver;
-      public getActiveCompactions_call(ByteBuffer login, String tserver, 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 {
+    public static class getActiveCompactions_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<ActiveCompaction>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tserver;
+      public getActiveCompactions_call(java.nio.ByteBuffer login, java.lang.String tserver, org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveCompaction>> 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.tserver = tserver;
@@ -5116,9 +5089,9 @@
         prot.writeMessageEnd();
       }
 
-      public List<ActiveCompaction> getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.util.List<ActiveCompaction> 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!");
+          throw new java.lang.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);
@@ -5126,16 +5099,16 @@
       }
     }
 
-    public void getSiteConfiguration(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getSiteConfiguration(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getSiteConfiguration_call method_call = new getSiteConfiguration_call(login, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getSiteConfiguration_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      public getSiteConfiguration_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 {
+    public static class getSiteConfiguration_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.lang.String>> {
+      private java.nio.ByteBuffer login;
+      public getSiteConfiguration_call(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> 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;
       }
@@ -5148,9 +5121,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,String> getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.lang.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!");
+          throw new java.lang.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);
@@ -5158,16 +5131,16 @@
       }
     }
 
-    public void getSystemConfiguration(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getSystemConfiguration(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getSystemConfiguration_call method_call = new getSystemConfiguration_call(login, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getSystemConfiguration_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      public getSystemConfiguration_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 {
+    public static class getSystemConfiguration_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.lang.String>> {
+      private java.nio.ByteBuffer login;
+      public getSystemConfiguration_call(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> 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;
       }
@@ -5180,9 +5153,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,String> getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.lang.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!");
+          throw new java.lang.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);
@@ -5190,16 +5163,16 @@
       }
     }
 
-    public void getTabletServers(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getTabletServers(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getTabletServers_call method_call = new getTabletServers_call(login, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getTabletServers_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      public getTabletServers_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 {
+    public static class getTabletServers_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<java.lang.String>> {
+      private java.nio.ByteBuffer login;
+      public getTabletServers_call(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> 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;
       }
@@ -5212,9 +5185,9 @@
         prot.writeMessageEnd();
       }
 
-      public List<String> getResult() throws org.apache.thrift.TException {
+      public java.util.List<java.lang.String> getResult() throws org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -5222,17 +5195,17 @@
       }
     }
 
-    public void removeProperty(ByteBuffer login, String property, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void removeProperty(java.nio.ByteBuffer login, java.lang.String property, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       removeProperty_call method_call = new removeProperty_call(login, property, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class removeProperty_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String property;
-      public removeProperty_call(ByteBuffer login, 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 {
+    public static class removeProperty_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String property;
+      public removeProperty_call(java.nio.ByteBuffer login, java.lang.String property, org.apache.thrift.async.AsyncMethodCallback<Void> 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.property = property;
@@ -5247,28 +5220,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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_removeProperty();
+        return null;
       }
     }
 
-    public void setProperty(ByteBuffer login, String property, String value, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void setProperty(java.nio.ByteBuffer login, java.lang.String property, java.lang.String value, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       setProperty_call method_call = new setProperty_call(login, property, value, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class setProperty_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String property;
-      private String value;
-      public setProperty_call(ByteBuffer login, 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 {
+    public static class setProperty_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String property;
+      private java.lang.String value;
+      public setProperty_call(java.nio.ByteBuffer login, java.lang.String property, java.lang.String value, org.apache.thrift.async.AsyncMethodCallback<Void> 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.property = property;
@@ -5285,28 +5258,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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_setProperty();
+        return null;
       }
     }
 
-    public void testClassLoad(ByteBuffer login, String className, String asTypeName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void testClassLoad(java.nio.ByteBuffer login, java.lang.String className, java.lang.String asTypeName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       testClassLoad_call method_call = new testClassLoad_call(login, className, asTypeName, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class testClassLoad_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String className;
-      private String asTypeName;
-      public testClassLoad_call(ByteBuffer login, 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 {
+    public static class testClassLoad_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String className;
+      private java.lang.String asTypeName;
+      public testClassLoad_call(java.nio.ByteBuffer login, java.lang.String className, java.lang.String asTypeName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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.className = className;
@@ -5323,9 +5296,9 @@
         prot.writeMessageEnd();
       }
 
-      public boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.lang.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!");
+          throw new java.lang.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);
@@ -5333,18 +5306,18 @@
       }
     }
 
-    public void authenticateUser(ByteBuffer login, String user, Map<String,String> properties, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void authenticateUser(java.nio.ByteBuffer login, java.lang.String user, java.util.Map<java.lang.String,java.lang.String> properties, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       authenticateUser_call method_call = new authenticateUser_call(login, user, properties, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class authenticateUser_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
-      private Map<String,String> properties;
-      public authenticateUser_call(ByteBuffer login, String user, Map<String,String> properties, 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 {
+    public static class authenticateUser_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      private java.util.Map<java.lang.String,java.lang.String> properties;
+      public authenticateUser_call(java.nio.ByteBuffer login, java.lang.String user, java.util.Map<java.lang.String,java.lang.String> properties, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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;
@@ -5361,9 +5334,9 @@
         prot.writeMessageEnd();
       }
 
-      public boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.lang.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!");
+          throw new java.lang.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);
@@ -5371,18 +5344,18 @@
       }
     }
 
-    public void changeUserAuthorizations(ByteBuffer login, String user, Set<ByteBuffer> authorizations, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void changeUserAuthorizations(java.nio.ByteBuffer login, java.lang.String user, java.util.Set<java.nio.ByteBuffer> authorizations, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       changeUserAuthorizations_call method_call = new changeUserAuthorizations_call(login, user, authorizations, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class changeUserAuthorizations_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
-      private Set<ByteBuffer> authorizations;
-      public changeUserAuthorizations_call(ByteBuffer login, String user, Set<ByteBuffer> authorizations, 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 {
+    public static class changeUserAuthorizations_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      private java.util.Set<java.nio.ByteBuffer> authorizations;
+      public changeUserAuthorizations_call(java.nio.ByteBuffer login, java.lang.String user, java.util.Set<java.nio.ByteBuffer> authorizations, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -5399,28 +5372,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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_changeUserAuthorizations();
+        return null;
       }
     }
 
-    public void changeLocalUserPassword(ByteBuffer login, String user, ByteBuffer password, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void changeLocalUserPassword(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       changeLocalUserPassword_call method_call = new changeLocalUserPassword_call(login, user, password, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class changeLocalUserPassword_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
-      private ByteBuffer password;
-      public changeLocalUserPassword_call(ByteBuffer login, String user, ByteBuffer password, 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 {
+    public static class changeLocalUserPassword_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      private java.nio.ByteBuffer password;
+      public changeLocalUserPassword_call(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -5437,28 +5410,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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_changeLocalUserPassword();
+        return null;
       }
     }
 
-    public void createLocalUser(ByteBuffer login, String user, ByteBuffer password, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void createLocalUser(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       createLocalUser_call method_call = new createLocalUser_call(login, user, password, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class createLocalUser_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
-      private ByteBuffer password;
-      public createLocalUser_call(ByteBuffer login, String user, ByteBuffer password, 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 {
+    public static class createLocalUser_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      private java.nio.ByteBuffer password;
+      public createLocalUser_call(java.nio.ByteBuffer login, java.lang.String user, java.nio.ByteBuffer password, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -5475,27 +5448,27 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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_createLocalUser();
+        return null;
       }
     }
 
-    public void dropLocalUser(ByteBuffer login, String user, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void dropLocalUser(java.nio.ByteBuffer login, java.lang.String user, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       dropLocalUser_call method_call = new dropLocalUser_call(login, user, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class dropLocalUser_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
-      public dropLocalUser_call(ByteBuffer login, String user, 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 {
+    public static class dropLocalUser_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      public dropLocalUser_call(java.nio.ByteBuffer login, java.lang.String user, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -5510,27 +5483,27 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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_dropLocalUser();
+        return null;
       }
     }
 
-    public void getUserAuthorizations(ByteBuffer login, String user, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getUserAuthorizations(java.nio.ByteBuffer login, java.lang.String user, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getUserAuthorizations_call method_call = new getUserAuthorizations_call(login, user, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getUserAuthorizations_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
-      public getUserAuthorizations_call(ByteBuffer login, String user, 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 {
+    public static class getUserAuthorizations_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<java.nio.ByteBuffer>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      public getUserAuthorizations_call(java.nio.ByteBuffer login, java.lang.String user, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>> 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;
@@ -5545,9 +5518,9 @@
         prot.writeMessageEnd();
       }
 
-      public List<ByteBuffer> getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.util.List<java.nio.ByteBuffer> 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!");
+          throw new java.lang.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);
@@ -5555,18 +5528,18 @@
       }
     }
 
-    public void grantSystemPermission(ByteBuffer login, String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void grantSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       grantSystemPermission_call method_call = new grantSystemPermission_call(login, user, perm, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class grantSystemPermission_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
+    public static class grantSystemPermission_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
       private SystemPermission perm;
-      public grantSystemPermission_call(ByteBuffer login, String user, SystemPermission 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 {
+      public grantSystemPermission_call(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -5583,29 +5556,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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_grantSystemPermission();
+        return null;
       }
     }
 
-    public void grantTablePermission(ByteBuffer login, String user, String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void grantTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       grantTablePermission_call method_call = new grantTablePermission_call(login, user, table, perm, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class grantTablePermission_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
-      private String table;
+    public static class grantTablePermission_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      private java.lang.String table;
       private TablePermission perm;
-      public grantTablePermission_call(ByteBuffer login, String user, String table, TablePermission 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 {
+      public grantTablePermission_call(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -5624,28 +5597,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_grantTablePermission();
+        return null;
       }
     }
 
-    public void hasSystemPermission(ByteBuffer login, String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void hasSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       hasSystemPermission_call method_call = new hasSystemPermission_call(login, user, perm, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class hasSystemPermission_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
+    public static class hasSystemPermission_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
       private SystemPermission perm;
-      public hasSystemPermission_call(ByteBuffer login, String user, SystemPermission 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 {
+      public hasSystemPermission_call(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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;
@@ -5662,9 +5635,9 @@
         prot.writeMessageEnd();
       }
 
-      public boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.lang.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!");
+          throw new java.lang.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);
@@ -5672,19 +5645,19 @@
       }
     }
 
-    public void hasTablePermission(ByteBuffer login, String user, String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void hasTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       hasTablePermission_call method_call = new hasTablePermission_call(login, user, table, perm, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class hasTablePermission_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
-      private String table;
+    public static class hasTablePermission_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      private java.lang.String table;
       private TablePermission perm;
-      public hasTablePermission_call(ByteBuffer login, String user, String table, TablePermission 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 {
+      public hasTablePermission_call(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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;
@@ -5703,9 +5676,9 @@
         prot.writeMessageEnd();
       }
 
-      public boolean getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.lang.Boolean getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -5713,16 +5686,16 @@
       }
     }
 
-    public void listLocalUsers(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void listLocalUsers(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       listLocalUsers_call method_call = new listLocalUsers_call(login, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class listLocalUsers_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      public listLocalUsers_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 {
+    public static class listLocalUsers_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Set<java.lang.String>> {
+      private java.nio.ByteBuffer login;
+      public listLocalUsers_call(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> 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;
       }
@@ -5735,9 +5708,9 @@
         prot.writeMessageEnd();
       }
 
-      public Set<String> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.util.Set<java.lang.String> getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -5745,18 +5718,18 @@
       }
     }
 
-    public void revokeSystemPermission(ByteBuffer login, String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void revokeSystemPermission(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       revokeSystemPermission_call method_call = new revokeSystemPermission_call(login, user, perm, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class revokeSystemPermission_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
+    public static class revokeSystemPermission_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
       private SystemPermission perm;
-      public revokeSystemPermission_call(ByteBuffer login, String user, SystemPermission 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 {
+      public revokeSystemPermission_call(java.nio.ByteBuffer login, java.lang.String user, SystemPermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -5773,29 +5746,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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_revokeSystemPermission();
+        return null;
       }
     }
 
-    public void revokeTablePermission(ByteBuffer login, String user, String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void revokeTablePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       revokeTablePermission_call method_call = new revokeTablePermission_call(login, user, table, perm, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class revokeTablePermission_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String user;
-      private String table;
+    public static class revokeTablePermission_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      private java.lang.String table;
       private TablePermission perm;
-      public revokeTablePermission_call(ByteBuffer login, String user, String table, TablePermission 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 {
+      public revokeTablePermission_call(java.nio.ByteBuffer login, java.lang.String user, java.lang.String table, TablePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -5814,29 +5787,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_revokeTablePermission();
+        return null;
       }
     }
 
-    public void grantNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void grantNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
+    public static class grantNamespacePermission_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      private java.lang.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 {
+      public grantNamespacePermission_call(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -5855,29 +5828,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    public void hasNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void hasNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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;
+    public static class hasNamespacePermission_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      private java.lang.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 {
+      public hasNamespacePermission_call(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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;
@@ -5896,9 +5869,9 @@
         prot.writeMessageEnd();
       }
 
-      public boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.lang.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!");
+          throw new java.lang.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);
@@ -5906,19 +5879,19 @@
       }
     }
 
-    public void revokeNamespacePermission(ByteBuffer login, String user, String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void revokeNamespacePermission(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
+    public static class revokeNamespacePermission_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String user;
+      private java.lang.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 {
+      public revokeNamespacePermission_call(java.nio.ByteBuffer login, java.lang.String user, java.lang.String namespaceName, NamespacePermission perm, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -5937,28 +5910,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    public void createBatchScanner(ByteBuffer login, String tableName, BatchScanOptions options, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void createBatchScanner(java.nio.ByteBuffer login, java.lang.String tableName, BatchScanOptions options, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       createBatchScanner_call method_call = new createBatchScanner_call(login, tableName, options, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class createBatchScanner_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class createBatchScanner_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private BatchScanOptions options;
-      public createBatchScanner_call(ByteBuffer login, String tableName, BatchScanOptions options, 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 {
+      public createBatchScanner_call(java.nio.ByteBuffer login, java.lang.String tableName, BatchScanOptions options, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> 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.tableName = tableName;
@@ -5975,9 +5948,9 @@
         prot.writeMessageEnd();
       }
 
-      public String getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.lang.String getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -5985,18 +5958,18 @@
       }
     }
 
-    public void createScanner(ByteBuffer login, String tableName, ScanOptions options, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void createScanner(java.nio.ByteBuffer login, java.lang.String tableName, ScanOptions options, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       createScanner_call method_call = new createScanner_call(login, tableName, options, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class createScanner_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class createScanner_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private ScanOptions options;
-      public createScanner_call(ByteBuffer login, String tableName, ScanOptions options, 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 {
+      public createScanner_call(java.nio.ByteBuffer login, java.lang.String tableName, ScanOptions options, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> 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.tableName = tableName;
@@ -6013,9 +5986,9 @@
         prot.writeMessageEnd();
       }
 
-      public String getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.lang.String getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6023,16 +5996,16 @@
       }
     }
 
-    public void hasNext(String scanner, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void hasNext(java.lang.String scanner, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       hasNext_call method_call = new hasNext_call(scanner, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class hasNext_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String scanner;
-      public hasNext_call(String scanner, 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 {
+    public static class hasNext_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
+      private java.lang.String scanner;
+      public hasNext_call(java.lang.String scanner, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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.scanner = scanner;
       }
@@ -6045,9 +6018,9 @@
         prot.writeMessageEnd();
       }
 
-      public boolean getResult() throws UnknownScanner, org.apache.thrift.TException {
+      public java.lang.Boolean getResult() throws UnknownScanner, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6055,16 +6028,16 @@
       }
     }
 
-    public void nextEntry(String scanner, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void nextEntry(java.lang.String scanner, org.apache.thrift.async.AsyncMethodCallback<KeyValueAndPeek> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       nextEntry_call method_call = new nextEntry_call(scanner, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class nextEntry_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String scanner;
-      public nextEntry_call(String scanner, 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 {
+    public static class nextEntry_call extends org.apache.thrift.async.TAsyncMethodCall<KeyValueAndPeek> {
+      private java.lang.String scanner;
+      public nextEntry_call(java.lang.String scanner, org.apache.thrift.async.AsyncMethodCallback<KeyValueAndPeek> 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.scanner = scanner;
       }
@@ -6079,7 +6052,7 @@
 
       public KeyValueAndPeek getResult() throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6087,17 +6060,17 @@
       }
     }
 
-    public void nextK(String scanner, int k, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void nextK(java.lang.String scanner, int k, org.apache.thrift.async.AsyncMethodCallback<ScanResult> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       nextK_call method_call = new nextK_call(scanner, k, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class nextK_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String scanner;
+    public static class nextK_call extends org.apache.thrift.async.TAsyncMethodCall<ScanResult> {
+      private java.lang.String scanner;
       private int k;
-      public nextK_call(String scanner, int k, 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 {
+      public nextK_call(java.lang.String scanner, int k, org.apache.thrift.async.AsyncMethodCallback<ScanResult> 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.scanner = scanner;
         this.k = k;
@@ -6114,7 +6087,7 @@
 
       public ScanResult getResult() throws NoMoreEntriesException, UnknownScanner, AccumuloSecurityException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6122,16 +6095,16 @@
       }
     }
 
-    public void closeScanner(String scanner, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void closeScanner(java.lang.String scanner, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       closeScanner_call method_call = new closeScanner_call(scanner, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class closeScanner_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String scanner;
-      public closeScanner_call(String scanner, 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 {
+    public static class closeScanner_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.lang.String scanner;
+      public closeScanner_call(java.lang.String scanner, org.apache.thrift.async.AsyncMethodCallback<Void> 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.scanner = scanner;
       }
@@ -6144,28 +6117,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws UnknownScanner, org.apache.thrift.TException {
+      public Void getResult() throws UnknownScanner, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_closeScanner();
+        return null;
       }
     }
 
-    public void updateAndFlush(ByteBuffer login, String tableName, Map<ByteBuffer,List<ColumnUpdate>> cells, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void updateAndFlush(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       updateAndFlush_call method_call = new updateAndFlush_call(login, tableName, cells, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class updateAndFlush_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private Map<ByteBuffer,List<ColumnUpdate>> cells;
-      public updateAndFlush_call(ByteBuffer login, String tableName, Map<ByteBuffer,List<ColumnUpdate>> cells, 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 {
+    public static class updateAndFlush_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells;
+      public updateAndFlush_call(java.nio.ByteBuffer login, java.lang.String tableName, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells, org.apache.thrift.async.AsyncMethodCallback<Void> 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.tableName = tableName;
@@ -6182,28 +6155,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, MutationsRejectedException, org.apache.thrift.TException {
+      public Void getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, MutationsRejectedException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_updateAndFlush();
+        return null;
       }
     }
 
-    public void createWriter(ByteBuffer login, String tableName, WriterOptions opts, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void createWriter(java.nio.ByteBuffer login, java.lang.String tableName, WriterOptions opts, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       createWriter_call method_call = new createWriter_call(login, tableName, opts, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class createWriter_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class createWriter_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private WriterOptions opts;
-      public createWriter_call(ByteBuffer login, String tableName, WriterOptions opts, 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 {
+      public createWriter_call(java.nio.ByteBuffer login, java.lang.String tableName, WriterOptions opts, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> 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.tableName = tableName;
@@ -6220,9 +6193,9 @@
         prot.writeMessageEnd();
       }
 
-      public String getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.lang.String getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6230,17 +6203,17 @@
       }
     }
 
-    public void update(String writer, Map<ByteBuffer,List<ColumnUpdate>> cells, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void update(java.lang.String writer, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       update_call method_call = new update_call(writer, cells, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class update_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String writer;
-      private Map<ByteBuffer,List<ColumnUpdate>> cells;
-      public update_call(String writer, Map<ByteBuffer,List<ColumnUpdate>> cells, 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 {
+    public static class update_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.lang.String writer;
+      private java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells;
+      public update_call(java.lang.String writer, java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells, org.apache.thrift.async.AsyncMethodCallback<Void> 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, true);
         this.writer = writer;
         this.cells = cells;
@@ -6255,25 +6228,26 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws org.apache.thrift.TException {
+      public Void getResult() throws org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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 null;
       }
     }
 
-    public void flush(String writer, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void flush(java.lang.String writer, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       flush_call method_call = new flush_call(writer, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class flush_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String writer;
-      public flush_call(String writer, 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 {
+    public static class flush_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.lang.String writer;
+      public flush_call(java.lang.String writer, org.apache.thrift.async.AsyncMethodCallback<Void> 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.writer = writer;
       }
@@ -6286,26 +6260,26 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException {
+      public Void getResult() throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_flush();
+        return null;
       }
     }
 
-    public void closeWriter(String writer, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void closeWriter(java.lang.String writer, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       closeWriter_call method_call = new closeWriter_call(writer, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class closeWriter_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String writer;
-      public closeWriter_call(String writer, 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 {
+    public static class closeWriter_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.lang.String writer;
+      public closeWriter_call(java.lang.String writer, org.apache.thrift.async.AsyncMethodCallback<Void> 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.writer = writer;
       }
@@ -6318,29 +6292,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException {
+      public Void getResult() throws UnknownWriter, MutationsRejectedException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_closeWriter();
+        return null;
       }
     }
 
-    public void updateRowConditionally(ByteBuffer login, String tableName, ByteBuffer row, ConditionalUpdates updates, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void updateRowConditionally(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer row, ConditionalUpdates updates, org.apache.thrift.async.AsyncMethodCallback<ConditionalStatus> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       updateRowConditionally_call method_call = new updateRowConditionally_call(login, tableName, row, updates, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class updateRowConditionally_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
-      private ByteBuffer row;
+    public static class updateRowConditionally_call extends org.apache.thrift.async.TAsyncMethodCall<ConditionalStatus> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
+      private java.nio.ByteBuffer row;
       private ConditionalUpdates updates;
-      public updateRowConditionally_call(ByteBuffer login, String tableName, ByteBuffer row, ConditionalUpdates updates, 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 {
+      public updateRowConditionally_call(java.nio.ByteBuffer login, java.lang.String tableName, java.nio.ByteBuffer row, ConditionalUpdates updates, org.apache.thrift.async.AsyncMethodCallback<ConditionalStatus> 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.tableName = tableName;
@@ -6361,7 +6335,7 @@
 
       public ConditionalStatus getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6369,18 +6343,18 @@
       }
     }
 
-    public void createConditionalWriter(ByteBuffer login, String tableName, ConditionalWriterOptions options, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void createConditionalWriter(java.nio.ByteBuffer login, java.lang.String tableName, ConditionalWriterOptions options, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       createConditionalWriter_call method_call = new createConditionalWriter_call(login, tableName, options, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class createConditionalWriter_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer login;
-      private String tableName;
+    public static class createConditionalWriter_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String tableName;
       private ConditionalWriterOptions options;
-      public createConditionalWriter_call(ByteBuffer login, String tableName, ConditionalWriterOptions options, 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 {
+      public createConditionalWriter_call(java.nio.ByteBuffer login, java.lang.String tableName, ConditionalWriterOptions options, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> 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.tableName = tableName;
@@ -6397,9 +6371,9 @@
         prot.writeMessageEnd();
       }
 
-      public String getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
+      public java.lang.String getResult() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6407,17 +6381,17 @@
       }
     }
 
-    public void updateRowsConditionally(String conditionalWriter, Map<ByteBuffer,ConditionalUpdates> updates, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void updateRowsConditionally(java.lang.String conditionalWriter, java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.nio.ByteBuffer,ConditionalStatus>> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       updateRowsConditionally_call method_call = new updateRowsConditionally_call(conditionalWriter, updates, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class updateRowsConditionally_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String conditionalWriter;
-      private Map<ByteBuffer,ConditionalUpdates> updates;
-      public updateRowsConditionally_call(String conditionalWriter, Map<ByteBuffer,ConditionalUpdates> updates, 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 {
+    public static class updateRowsConditionally_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.nio.ByteBuffer,ConditionalStatus>> {
+      private java.lang.String conditionalWriter;
+      private java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates;
+      public updateRowsConditionally_call(java.lang.String conditionalWriter, java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.nio.ByteBuffer,ConditionalStatus>> 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.conditionalWriter = conditionalWriter;
         this.updates = updates;
@@ -6432,9 +6406,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<ByteBuffer,ConditionalStatus> getResult() throws UnknownWriter, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.util.Map<java.nio.ByteBuffer,ConditionalStatus> getResult() throws UnknownWriter, AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6442,16 +6416,16 @@
       }
     }
 
-    public void closeConditionalWriter(String conditionalWriter, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void closeConditionalWriter(java.lang.String conditionalWriter, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       closeConditionalWriter_call method_call = new closeConditionalWriter_call(conditionalWriter, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class closeConditionalWriter_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String conditionalWriter;
-      public closeConditionalWriter_call(String conditionalWriter, 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 {
+    public static class closeConditionalWriter_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.lang.String conditionalWriter;
+      public closeConditionalWriter_call(java.lang.String conditionalWriter, org.apache.thrift.async.AsyncMethodCallback<Void> 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.conditionalWriter = conditionalWriter;
       }
@@ -6464,26 +6438,26 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws org.apache.thrift.TException {
+      public Void getResult() throws org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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_closeConditionalWriter();
+        return null;
       }
     }
 
-    public void getRowRange(ByteBuffer row, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getRowRange(java.nio.ByteBuffer row, org.apache.thrift.async.AsyncMethodCallback<Range> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getRowRange_call method_call = new getRowRange_call(row, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getRowRange_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private ByteBuffer row;
-      public getRowRange_call(ByteBuffer row, 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 {
+    public static class getRowRange_call extends org.apache.thrift.async.TAsyncMethodCall<Range> {
+      private java.nio.ByteBuffer row;
+      public getRowRange_call(java.nio.ByteBuffer row, org.apache.thrift.async.AsyncMethodCallback<Range> 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.row = row;
       }
@@ -6498,7 +6472,7 @@
 
       public Range getResult() throws org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6506,17 +6480,17 @@
       }
     }
 
-    public void getFollowing(Key key, PartialKey part, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getFollowing(Key key, PartialKey part, org.apache.thrift.async.AsyncMethodCallback<Key> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       getFollowing_call method_call = new getFollowing_call(key, part, resultHandler, this, ___protocolFactory, ___transport);
       this.___currentMethod = method_call;
       ___manager.call(method_call);
     }
 
-    public static class getFollowing_call extends org.apache.thrift.async.TAsyncMethodCall {
+    public static class getFollowing_call extends org.apache.thrift.async.TAsyncMethodCall<Key> {
       private Key key;
       private PartialKey part;
-      public getFollowing_call(Key key, PartialKey part, 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 {
+      public getFollowing_call(Key key, PartialKey part, org.apache.thrift.async.AsyncMethodCallback<Key> 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.key = key;
         this.part = part;
@@ -6533,7 +6507,7 @@
 
       public Key getResult() throws org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6541,15 +6515,15 @@
       }
     }
 
-    public void systemNamespace(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void systemNamespace(org.apache.thrift.async.AsyncMethodCallback<java.lang.String> 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 {
+    public static class systemNamespace_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
+      public systemNamespace_call(org.apache.thrift.async.AsyncMethodCallback<java.lang.String> 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);
       }
 
@@ -6560,9 +6534,9 @@
         prot.writeMessageEnd();
       }
 
-      public String getResult() throws org.apache.thrift.TException {
+      public java.lang.String getResult() throws org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6570,15 +6544,15 @@
       }
     }
 
-    public void defaultNamespace(org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void defaultNamespace(org.apache.thrift.async.AsyncMethodCallback<java.lang.String> 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 {
+    public static class defaultNamespace_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
+      public defaultNamespace_call(org.apache.thrift.async.AsyncMethodCallback<java.lang.String> 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);
       }
 
@@ -6589,9 +6563,9 @@
         prot.writeMessageEnd();
       }
 
-      public String getResult() throws org.apache.thrift.TException {
+      public java.lang.String getResult() throws org.apache.thrift.TException {
         if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
+          throw new java.lang.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);
@@ -6599,16 +6573,16 @@
       }
     }
 
-    public void listNamespaces(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void listNamespaces(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> 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 {
+    public static class listNamespaces_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<java.lang.String>> {
+      private java.nio.ByteBuffer login;
+      public listNamespaces_call(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> 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;
       }
@@ -6621,9 +6595,9 @@
         prot.writeMessageEnd();
       }
 
-      public List<String> getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.util.List<java.lang.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!");
+          throw new java.lang.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);
@@ -6631,17 +6605,17 @@
       }
     }
 
-    public void namespaceExists(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void namespaceExists(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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 {
+    public static class namespaceExists_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      public namespaceExists_call(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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;
@@ -6656,9 +6630,9 @@
         prot.writeMessageEnd();
       }
 
-      public boolean getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.lang.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!");
+          throw new java.lang.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);
@@ -6666,17 +6640,17 @@
       }
     }
 
-    public void createNamespace(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void createNamespace(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<Void> 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 {
+    public static class createNamespace_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      public createNamespace_call(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -6691,27 +6665,27 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceExistsException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    public void deleteNamespace(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void deleteNamespace(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<Void> 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 {
+    public static class deleteNamespace_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      public deleteNamespace_call(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -6726,28 +6700,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceNotEmptyException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    public void renameNamespace(ByteBuffer login, String oldNamespaceName, String newNamespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void renameNamespace(java.nio.ByteBuffer login, java.lang.String oldNamespaceName, java.lang.String newNamespaceName, org.apache.thrift.async.AsyncMethodCallback<Void> 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 {
+    public static class renameNamespace_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String oldNamespaceName;
+      private java.lang.String newNamespaceName;
+      public renameNamespace_call(java.nio.ByteBuffer login, java.lang.String oldNamespaceName, java.lang.String newNamespaceName, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -6764,29 +6738,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, NamespaceExistsException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    public void setNamespaceProperty(ByteBuffer login, String namespaceName, String property, String value, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void setNamespaceProperty(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property, java.lang.String value, org.apache.thrift.async.AsyncMethodCallback<Void> 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 {
+    public static class setNamespaceProperty_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      private java.lang.String property;
+      private java.lang.String value;
+      public setNamespaceProperty_call(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property, java.lang.String value, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -6805,28 +6779,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    public void removeNamespaceProperty(ByteBuffer login, String namespaceName, String property, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void removeNamespaceProperty(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property, org.apache.thrift.async.AsyncMethodCallback<Void> 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 {
+    public static class removeNamespaceProperty_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      private java.lang.String property;
+      public removeNamespaceProperty_call(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String property, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -6843,27 +6817,27 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    public void getNamespaceProperties(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getNamespaceProperties(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> 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 {
+    public static class getNamespaceProperties_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.lang.String>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      public getNamespaceProperties_call(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> 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;
@@ -6878,9 +6852,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,String> getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.lang.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!");
+          throw new java.lang.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);
@@ -6888,16 +6862,16 @@
       }
     }
 
-    public void namespaceIdMap(ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void namespaceIdMap(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> 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 {
+    public static class namespaceIdMap_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.lang.String>> {
+      private java.nio.ByteBuffer login;
+      public namespaceIdMap_call(java.nio.ByteBuffer login, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> 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;
       }
@@ -6910,9 +6884,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,String> getResult() throws AccumuloException, AccumuloSecurityException, org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.lang.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!");
+          throw new java.lang.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);
@@ -6920,19 +6894,19 @@
       }
     }
 
-    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 attachNamespaceIterator(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
+    public static class attachNamespaceIterator_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.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 {
+      private java.util.Set<IteratorScope> scopes;
+      public attachNamespaceIterator_call(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -6951,29 +6925,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    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 removeNamespaceIterator(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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 {
+    public static class removeNamespaceIterator_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      private java.lang.String name;
+      private java.util.Set<IteratorScope> scopes;
+      public removeNamespaceIterator_call(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -6992,29 +6966,29 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    public void getNamespaceIteratorSetting(ByteBuffer login, String namespaceName, String name, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void getNamespaceIteratorSetting(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> 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;
+    public static class getNamespaceIteratorSetting_call extends org.apache.thrift.async.TAsyncMethodCall<IteratorSetting> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      private java.lang.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 {
+      public getNamespaceIteratorSetting_call(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String name, IteratorScope scope, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> 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;
@@ -7035,7 +7009,7 @@
 
       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!");
+          throw new java.lang.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);
@@ -7043,17 +7017,17 @@
       }
     }
 
-    public void listNamespaceIterators(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void listNamespaceIterators(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> 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 {
+    public static class listNamespaceIterators_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      public listNamespaceIterators_call(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> 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;
@@ -7068,9 +7042,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,Set<IteratorScope>> getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.util.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!");
+          throw new java.lang.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);
@@ -7078,19 +7052,19 @@
       }
     }
 
-    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 checkNamespaceIteratorConflicts(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
+    public static class checkNamespaceIteratorConflicts_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.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 {
+      private java.util.Set<IteratorScope> scopes;
+      public checkNamespaceIteratorConflicts_call(java.nio.ByteBuffer login, java.lang.String namespaceName, IteratorSetting setting, java.util.Set<IteratorScope> scopes, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -7109,28 +7083,28 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    public void addNamespaceConstraint(ByteBuffer login, String namespaceName, String constraintClassName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void addNamespaceConstraint(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String constraintClassName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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 {
+    public static class addNamespaceConstraint_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Integer> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      private java.lang.String constraintClassName;
+      public addNamespaceConstraint_call(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String constraintClassName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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;
@@ -7147,9 +7121,9 @@
         prot.writeMessageEnd();
       }
 
-      public int getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      public java.lang.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!");
+          throw new java.lang.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);
@@ -7157,18 +7131,18 @@
       }
     }
 
-    public void removeNamespaceConstraint(ByteBuffer login, String namespaceName, int id, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void removeNamespaceConstraint(java.nio.ByteBuffer login, java.lang.String namespaceName, int id, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
+    public static class removeNamespaceConstraint_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private java.nio.ByteBuffer login;
+      private java.lang.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 {
+      public removeNamespaceConstraint_call(java.nio.ByteBuffer login, java.lang.String namespaceName, int id, org.apache.thrift.async.AsyncMethodCallback<Void> 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;
@@ -7185,27 +7159,27 @@
         prot.writeMessageEnd();
       }
 
-      public void getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      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!");
+          throw new java.lang.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();
+        return null;
       }
     }
 
-    public void listNamespaceConstraints(ByteBuffer login, String namespaceName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void listNamespaceConstraints(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>> 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 {
+    public static class listNamespaceConstraints_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.Map<java.lang.String,java.lang.Integer>> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      public listNamespaceConstraints_call(java.nio.ByteBuffer login, java.lang.String namespaceName, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>> 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;
@@ -7220,9 +7194,9 @@
         prot.writeMessageEnd();
       }
 
-      public Map<String,Integer> getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      public java.util.Map<java.lang.String,java.lang.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!");
+          throw new java.lang.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);
@@ -7230,19 +7204,19 @@
       }
     }
 
-    public void testNamespaceClassLoad(ByteBuffer login, String namespaceName, String className, String asTypeName, org.apache.thrift.async.AsyncMethodCallback resultHandler) throws org.apache.thrift.TException {
+    public void testNamespaceClassLoad(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String className, java.lang.String asTypeName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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 {
+    public static class testNamespaceClassLoad_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
+      private java.nio.ByteBuffer login;
+      private java.lang.String namespaceName;
+      private java.lang.String className;
+      private java.lang.String asTypeName;
+      public testNamespaceClassLoad_call(java.nio.ByteBuffer login, java.lang.String namespaceName, java.lang.String className, java.lang.String asTypeName, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> 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;
@@ -7261,9 +7235,9 @@
         prot.writeMessageEnd();
       }
 
-      public boolean getResult() throws AccumuloException, AccumuloSecurityException, NamespaceNotFoundException, org.apache.thrift.TException {
+      public java.lang.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!");
+          throw new java.lang.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);
@@ -7274,16 +7248,16 @@
   }
 
   public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
-    private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
+    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(Processor.class.getName());
     public Processor(I iface) {
-      super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
+      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
     }
 
-    protected Processor(I iface, Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
+    protected Processor(I iface, java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
       super(iface, getProcessMap(processMap));
     }
 
-    private static <I extends Iface> Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> getProcessMap(Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
+    private static <I extends Iface> java.util.Map<java.lang.String,  org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
       processMap.put("login", new login());
       processMap.put("addConstraint", new addConstraint());
       processMap.put("addSplits", new addSplits());
@@ -10065,16 +10039,16 @@
   }
 
   public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> {
-    private static final Logger LOGGER = LoggerFactory.getLogger(AsyncProcessor.class.getName());
+    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());
     public AsyncProcessor(I iface) {
-      super(iface, getProcessMap(new HashMap<String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
+      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
     }
 
-    protected AsyncProcessor(I iface, Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
+    protected AsyncProcessor(I iface, java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
       super(iface, getProcessMap(processMap));
     }
 
-    private static <I extends AsyncIface> Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
+    private static <I extends AsyncIface> java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
       processMap.put("login", new login());
       processMap.put("addConstraint", new addConstraint());
       processMap.put("addSplits", new addSplits());
@@ -10178,7 +10152,7 @@
       return processMap;
     }
 
-    public static class login<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, login_args, ByteBuffer> {
+    public static class login<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, login_args, java.nio.ByteBuffer> {
       public login() {
         super("login");
       }
@@ -10187,41 +10161,49 @@
         return new login_args();
       }
 
-      public AsyncMethodCallback<ByteBuffer> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<ByteBuffer>() { 
-          public void onComplete(ByteBuffer o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer>() { 
+          public void onComplete(java.nio.ByteBuffer o) {
             login_result result = new login_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             login_result result = new login_result();
             if (e instanceof AccumuloSecurityException) {
-                        result.ouch2 = (AccumuloSecurityException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch2 = (AccumuloSecurityException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10230,12 +10212,12 @@
         return false;
       }
 
-      public void start(I iface, login_args args, org.apache.thrift.async.AsyncMethodCallback<ByteBuffer> resultHandler) throws TException {
+      public void start(I iface, login_args args, org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer> resultHandler) throws org.apache.thrift.TException {
         iface.login(args.principal, args.loginProperties,resultHandler);
       }
     }
 
-    public static class addConstraint<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addConstraint_args, Integer> {
+    public static class addConstraint<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addConstraint_args, java.lang.Integer> {
       public addConstraint() {
         super("addConstraint");
       }
@@ -10244,52 +10226,58 @@
         return new addConstraint_args();
       }
 
-      public AsyncMethodCallback<Integer> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Integer>() { 
-          public void onComplete(Integer o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer>() { 
+          public void onComplete(java.lang.Integer o) {
             addConstraint_result result = new addConstraint_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             addConstraint_result result = new addConstraint_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10298,7 +10286,7 @@
         return false;
       }
 
-      public void start(I iface, addConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws TException {
+      public void start(I iface, addConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
         iface.addConstraint(args.login, args.tableName, args.constraintClassName,resultHandler);
       }
     }
@@ -10312,50 +10300,56 @@
         return new addSplits_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             addSplits_result result = new addSplits_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             addSplits_result result = new addSplits_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10364,7 +10358,7 @@
         return false;
       }
 
-      public void start(I iface, addSplits_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, addSplits_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.addSplits(args.login, args.tableName, args.splits,resultHandler);
       }
     }
@@ -10378,50 +10372,56 @@
         return new attachIterator_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             attachIterator_result result = new attachIterator_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             attachIterator_result result = new attachIterator_result();
             if (e instanceof AccumuloSecurityException) {
-                        result.ouch1 = (AccumuloSecurityException) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloException) {
-                        result.ouch2 = (AccumuloException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (AccumuloSecurityException) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloException) {
+              result.ouch2 = (AccumuloException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10430,7 +10430,7 @@
         return false;
       }
 
-      public void start(I iface, attachIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, attachIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.attachIterator(args.login, args.tableName, args.setting, args.scopes,resultHandler);
       }
     }
@@ -10444,50 +10444,56 @@
         return new checkIteratorConflicts_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             checkIteratorConflicts_result result = new checkIteratorConflicts_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             checkIteratorConflicts_result result = new checkIteratorConflicts_result();
             if (e instanceof AccumuloSecurityException) {
-                        result.ouch1 = (AccumuloSecurityException) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloException) {
-                        result.ouch2 = (AccumuloException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (AccumuloSecurityException) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloException) {
+              result.ouch2 = (AccumuloException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10496,7 +10502,7 @@
         return false;
       }
 
-      public void start(I iface, checkIteratorConflicts_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, checkIteratorConflicts_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.checkIteratorConflicts(args.login, args.tableName, args.setting, args.scopes,resultHandler);
       }
     }
@@ -10510,40 +10516,48 @@
         return new clearLocatorCache_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             clearLocatorCache_result result = new clearLocatorCache_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             clearLocatorCache_result result = new clearLocatorCache_result();
             if (e instanceof TableNotFoundException) {
-                        result.ouch1 = (TableNotFoundException) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (TableNotFoundException) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10552,7 +10566,7 @@
         return false;
       }
 
-      public void start(I iface, clearLocatorCache_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, clearLocatorCache_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.clearLocatorCache(args.login, args.tableName,resultHandler);
       }
     }
@@ -10566,55 +10580,60 @@
         return new cloneTable_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             cloneTable_result result = new cloneTable_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             cloneTable_result result = new cloneTable_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof TableExistsException) {
-                        result.ouch4 = (TableExistsException) e;
-                        result.setOuch4IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof TableExistsException) {
+              result.ouch4 = (TableExistsException) e;
+              result.setOuch4IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10623,7 +10642,7 @@
         return false;
       }
 
-      public void start(I iface, cloneTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, cloneTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.cloneTable(args.login, args.tableName, args.newTableName, args.flush, args.propertiesToSet, args.propertiesToExclude,resultHandler);
       }
     }
@@ -10637,50 +10656,56 @@
         return new compactTable_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             compactTable_result result = new compactTable_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             compactTable_result result = new compactTable_result();
             if (e instanceof AccumuloSecurityException) {
-                        result.ouch1 = (AccumuloSecurityException) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof TableNotFoundException) {
-                        result.ouch2 = (TableNotFoundException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloException) {
-                        result.ouch3 = (AccumuloException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (AccumuloSecurityException) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof TableNotFoundException) {
+              result.ouch2 = (TableNotFoundException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloException) {
+              result.ouch3 = (AccumuloException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10689,7 +10714,7 @@
         return false;
       }
 
-      public void start(I iface, compactTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, compactTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.compactTable(args.login, args.tableName, args.startRow, args.endRow, args.iterators, args.flush, args.wait, args.compactionStrategy,resultHandler);
       }
     }
@@ -10703,50 +10728,56 @@
         return new cancelCompaction_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             cancelCompaction_result result = new cancelCompaction_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             cancelCompaction_result result = new cancelCompaction_result();
             if (e instanceof AccumuloSecurityException) {
-                        result.ouch1 = (AccumuloSecurityException) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof TableNotFoundException) {
-                        result.ouch2 = (TableNotFoundException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloException) {
-                        result.ouch3 = (AccumuloException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (AccumuloSecurityException) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof TableNotFoundException) {
+              result.ouch2 = (TableNotFoundException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloException) {
+              result.ouch3 = (AccumuloException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10755,7 +10786,7 @@
         return false;
       }
 
-      public void start(I iface, cancelCompaction_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, cancelCompaction_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.cancelCompaction(args.login, args.tableName,resultHandler);
       }
     }
@@ -10769,50 +10800,56 @@
         return new createTable_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             createTable_result result = new createTable_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             createTable_result result = new createTable_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 TableExistsException) {
-                        result.ouch3 = (TableExistsException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableExistsException) {
+              result.ouch3 = (TableExistsException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10821,7 +10858,7 @@
         return false;
       }
 
-      public void start(I iface, createTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, createTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.createTable(args.login, args.tableName, args.versioningIter, args.type,resultHandler);
       }
     }
@@ -10835,50 +10872,56 @@
         return new deleteTable_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             deleteTable_result result = new deleteTable_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             deleteTable_result result = new deleteTable_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10887,7 +10930,7 @@
         return false;
       }
 
-      public void start(I iface, deleteTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, deleteTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.deleteTable(args.login, args.tableName,resultHandler);
       }
     }
@@ -10901,50 +10944,56 @@
         return new deleteRows_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             deleteRows_result result = new deleteRows_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             deleteRows_result result = new deleteRows_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -10953,7 +11002,7 @@
         return false;
       }
 
-      public void start(I iface, deleteRows_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, deleteRows_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.deleteRows(args.login, args.tableName, args.startRow, args.endRow,resultHandler);
       }
     }
@@ -10967,50 +11016,56 @@
         return new exportTable_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             exportTable_result result = new exportTable_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             exportTable_result result = new exportTable_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11019,7 +11074,7 @@
         return false;
       }
 
-      public void start(I iface, exportTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, exportTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.exportTable(args.login, args.tableName, args.exportDir,resultHandler);
       }
     }
@@ -11033,50 +11088,56 @@
         return new flushTable_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             flushTable_result result = new flushTable_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             flushTable_result result = new flushTable_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11085,12 +11146,12 @@
         return false;
       }
 
-      public void start(I iface, flushTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, flushTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.flushTable(args.login, args.tableName, args.startRow, args.endRow, args.wait,resultHandler);
       }
     }
 
-    public static class getDiskUsage<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getDiskUsage_args, List<DiskUsage>> {
+    public static class getDiskUsage<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getDiskUsage_args, java.util.List<DiskUsage>> {
       public getDiskUsage() {
         super("getDiskUsage");
       }
@@ -11099,51 +11160,57 @@
         return new getDiskUsage_args();
       }
 
-      public AsyncMethodCallback<List<DiskUsage>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<DiskUsage>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<List<DiskUsage>>() { 
-          public void onComplete(List<DiskUsage> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<DiskUsage>>() { 
+          public void onComplete(java.util.List<DiskUsage> o) {
             getDiskUsage_result result = new getDiskUsage_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getDiskUsage_result result = new getDiskUsage_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11152,12 +11219,12 @@
         return false;
       }
 
-      public void start(I iface, getDiskUsage_args args, org.apache.thrift.async.AsyncMethodCallback<List<DiskUsage>> resultHandler) throws TException {
+      public void start(I iface, getDiskUsage_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<DiskUsage>> resultHandler) throws org.apache.thrift.TException {
         iface.getDiskUsage(args.login, args.tables,resultHandler);
       }
     }
 
-    public static class getLocalityGroups<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getLocalityGroups_args, Map<String,Set<String>>> {
+    public static class getLocalityGroups<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getLocalityGroups_args, java.util.Map<java.lang.String,java.util.Set<java.lang.String>>> {
       public getLocalityGroups() {
         super("getLocalityGroups");
       }
@@ -11166,51 +11233,57 @@
         return new getLocalityGroups_args();
       }
 
-      public AsyncMethodCallback<Map<String,Set<String>>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<java.lang.String>>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Map<String,Set<String>>>() { 
-          public void onComplete(Map<String,Set<String>> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<java.lang.String>>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.util.Set<java.lang.String>> o) {
             getLocalityGroups_result result = new getLocalityGroups_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getLocalityGroups_result result = new getLocalityGroups_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11219,7 +11292,7 @@
         return false;
       }
 
-      public void start(I iface, getLocalityGroups_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,Set<String>>> resultHandler) throws TException {
+      public void start(I iface, getLocalityGroups_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<java.lang.String>>> resultHandler) throws org.apache.thrift.TException {
         iface.getLocalityGroups(args.login, args.tableName,resultHandler);
       }
     }
@@ -11233,51 +11306,57 @@
         return new getIteratorSetting_args();
       }
 
-      public AsyncMethodCallback<IteratorSetting> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<IteratorSetting>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<IteratorSetting>() { 
           public void onComplete(IteratorSetting o) {
             getIteratorSetting_result result = new getIteratorSetting_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getIteratorSetting_result result = new getIteratorSetting_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11286,12 +11365,12 @@
         return false;
       }
 
-      public void start(I iface, getIteratorSetting_args args, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> resultHandler) throws TException {
+      public void start(I iface, getIteratorSetting_args args, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> resultHandler) throws org.apache.thrift.TException {
         iface.getIteratorSetting(args.login, args.tableName, args.iteratorName, args.scope,resultHandler);
       }
     }
 
-    public static class getMaxRow<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getMaxRow_args, ByteBuffer> {
+    public static class getMaxRow<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getMaxRow_args, java.nio.ByteBuffer> {
       public getMaxRow() {
         super("getMaxRow");
       }
@@ -11300,51 +11379,57 @@
         return new getMaxRow_args();
       }
 
-      public AsyncMethodCallback<ByteBuffer> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<ByteBuffer>() { 
-          public void onComplete(ByteBuffer o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer>() { 
+          public void onComplete(java.nio.ByteBuffer o) {
             getMaxRow_result result = new getMaxRow_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getMaxRow_result result = new getMaxRow_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11353,12 +11438,12 @@
         return false;
       }
 
-      public void start(I iface, getMaxRow_args args, org.apache.thrift.async.AsyncMethodCallback<ByteBuffer> resultHandler) throws TException {
+      public void start(I iface, getMaxRow_args args, org.apache.thrift.async.AsyncMethodCallback<java.nio.ByteBuffer> resultHandler) throws org.apache.thrift.TException {
         iface.getMaxRow(args.login, args.tableName, args.auths, args.startRow, args.startInclusive, args.endRow, args.endInclusive,resultHandler);
       }
     }
 
-    public static class getTableProperties<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getTableProperties_args, Map<String,String>> {
+    public static class getTableProperties<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getTableProperties_args, java.util.Map<java.lang.String,java.lang.String>> {
       public getTableProperties() {
         super("getTableProperties");
       }
@@ -11367,51 +11452,57 @@
         return new getTableProperties_args();
       }
 
-      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.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) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.lang.String> o) {
             getTableProperties_result result = new getTableProperties_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getTableProperties_result result = new getTableProperties_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11420,7 +11511,7 @@
         return false;
       }
 
-      public void start(I iface, getTableProperties_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
+      public void start(I iface, getTableProperties_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException {
         iface.getTableProperties(args.login, args.tableName,resultHandler);
       }
     }
@@ -11434,50 +11525,56 @@
         return new importDirectory_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             importDirectory_result result = new importDirectory_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             importDirectory_result result = new importDirectory_result();
             if (e instanceof TableNotFoundException) {
-                        result.ouch1 = (TableNotFoundException) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloException) {
-                        result.ouch3 = (AccumuloException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloSecurityException) {
-                        result.ouch4 = (AccumuloSecurityException) e;
-                        result.setOuch4IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (TableNotFoundException) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloException) {
+              result.ouch3 = (AccumuloException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloSecurityException) {
+              result.ouch4 = (AccumuloSecurityException) e;
+              result.setOuch4IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11486,7 +11583,7 @@
         return false;
       }
 
-      public void start(I iface, importDirectory_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, importDirectory_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.importDirectory(args.login, args.tableName, args.importDir, args.failureDir, args.setTime,resultHandler);
       }
     }
@@ -11500,50 +11597,56 @@
         return new importTable_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             importTable_result result = new importTable_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             importTable_result result = new importTable_result();
             if (e instanceof TableExistsException) {
-                        result.ouch1 = (TableExistsException) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloException) {
-                        result.ouch2 = (AccumuloException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloSecurityException) {
-                        result.ouch3 = (AccumuloSecurityException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (TableExistsException) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloException) {
+              result.ouch2 = (AccumuloException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloSecurityException) {
+              result.ouch3 = (AccumuloSecurityException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11552,12 +11655,12 @@
         return false;
       }
 
-      public void start(I iface, importTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, importTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.importTable(args.login, args.tableName, args.importDir,resultHandler);
       }
     }
 
-    public static class listSplits<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listSplits_args, List<ByteBuffer>> {
+    public static class listSplits<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listSplits_args, java.util.List<java.nio.ByteBuffer>> {
       public listSplits() {
         super("listSplits");
       }
@@ -11566,51 +11669,57 @@
         return new listSplits_args();
       }
 
-      public AsyncMethodCallback<List<ByteBuffer>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<List<ByteBuffer>>() { 
-          public void onComplete(List<ByteBuffer> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>>() { 
+          public void onComplete(java.util.List<java.nio.ByteBuffer> o) {
             listSplits_result result = new listSplits_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             listSplits_result result = new listSplits_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11619,12 +11728,12 @@
         return false;
       }
 
-      public void start(I iface, listSplits_args args, org.apache.thrift.async.AsyncMethodCallback<List<ByteBuffer>> resultHandler) throws TException {
+      public void start(I iface, listSplits_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>> resultHandler) throws org.apache.thrift.TException {
         iface.listSplits(args.login, args.tableName, args.maxSplits,resultHandler);
       }
     }
 
-    public static class listTables<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listTables_args, Set<String>> {
+    public static class listTables<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listTables_args, java.util.Set<java.lang.String>> {
       public listTables() {
         super("listTables");
       }
@@ -11633,35 +11742,45 @@
         return new listTables_args();
       }
 
-      public AsyncMethodCallback<Set<String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Set<String>>() { 
-          public void onComplete(Set<String> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>>() { 
+          public void onComplete(java.util.Set<java.lang.String> o) {
             listTables_result result = new listTables_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             listTables_result result = new listTables_result();
-            {
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11670,12 +11789,12 @@
         return false;
       }
 
-      public void start(I iface, listTables_args args, org.apache.thrift.async.AsyncMethodCallback<Set<String>> resultHandler) throws TException {
+      public void start(I iface, listTables_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> resultHandler) throws org.apache.thrift.TException {
         iface.listTables(args.login,resultHandler);
       }
     }
 
-    public static class listIterators<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listIterators_args, Map<String,Set<IteratorScope>>> {
+    public static class listIterators<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listIterators_args, java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> {
       public listIterators() {
         super("listIterators");
       }
@@ -11684,51 +11803,57 @@
         return new listIterators_args();
       }
 
-      public AsyncMethodCallback<Map<String,Set<IteratorScope>>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.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) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.util.Set<IteratorScope>> o) {
             listIterators_result result = new listIterators_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             listIterators_result result = new listIterators_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11737,12 +11862,12 @@
         return false;
       }
 
-      public void start(I iface, listIterators_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,Set<IteratorScope>>> resultHandler) throws TException {
+      public void start(I iface, listIterators_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> resultHandler) throws org.apache.thrift.TException {
         iface.listIterators(args.login, args.tableName,resultHandler);
       }
     }
 
-    public static class listConstraints<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listConstraints_args, Map<String,Integer>> {
+    public static class listConstraints<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listConstraints_args, java.util.Map<java.lang.String,java.lang.Integer>> {
       public listConstraints() {
         super("listConstraints");
       }
@@ -11751,51 +11876,57 @@
         return new listConstraints_args();
       }
 
-      public AsyncMethodCallback<Map<String,Integer>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.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) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.lang.Integer> o) {
             listConstraints_result result = new listConstraints_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             listConstraints_result result = new listConstraints_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11804,7 +11935,7 @@
         return false;
       }
 
-      public void start(I iface, listConstraints_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,Integer>> resultHandler) throws TException {
+      public void start(I iface, listConstraints_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>> resultHandler) throws org.apache.thrift.TException {
         iface.listConstraints(args.login, args.tableName,resultHandler);
       }
     }
@@ -11818,50 +11949,56 @@
         return new mergeTablets_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             mergeTablets_result result = new mergeTablets_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             mergeTablets_result result = new mergeTablets_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11870,7 +12007,7 @@
         return false;
       }
 
-      public void start(I iface, mergeTablets_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, mergeTablets_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.mergeTablets(args.login, args.tableName, args.startRow, args.endRow,resultHandler);
       }
     }
@@ -11884,50 +12021,56 @@
         return new offlineTable_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             offlineTable_result result = new offlineTable_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             offlineTable_result result = new offlineTable_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -11936,7 +12079,7 @@
         return false;
       }
 
-      public void start(I iface, offlineTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, offlineTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.offlineTable(args.login, args.tableName, args.wait,resultHandler);
       }
     }
@@ -11950,50 +12093,56 @@
         return new onlineTable_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             onlineTable_result result = new onlineTable_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             onlineTable_result result = new onlineTable_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12002,7 +12151,7 @@
         return false;
       }
 
-      public void start(I iface, onlineTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, onlineTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.onlineTable(args.login, args.tableName, args.wait,resultHandler);
       }
     }
@@ -12016,50 +12165,56 @@
         return new removeConstraint_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             removeConstraint_result result = new removeConstraint_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             removeConstraint_result result = new removeConstraint_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12068,7 +12223,7 @@
         return false;
       }
 
-      public void start(I iface, removeConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, removeConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.removeConstraint(args.login, args.tableName, args.constraint,resultHandler);
       }
     }
@@ -12082,50 +12237,56 @@
         return new removeIterator_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             removeIterator_result result = new removeIterator_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             removeIterator_result result = new removeIterator_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12134,7 +12295,7 @@
         return false;
       }
 
-      public void start(I iface, removeIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, removeIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.removeIterator(args.login, args.tableName, args.iterName, args.scopes,resultHandler);
       }
     }
@@ -12148,50 +12309,56 @@
         return new removeTableProperty_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             removeTableProperty_result result = new removeTableProperty_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             removeTableProperty_result result = new removeTableProperty_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12200,7 +12367,7 @@
         return false;
       }
 
-      public void start(I iface, removeTableProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, removeTableProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.removeTableProperty(args.login, args.tableName, args.property,resultHandler);
       }
     }
@@ -12214,55 +12381,60 @@
         return new renameTable_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             renameTable_result result = new renameTable_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             renameTable_result result = new renameTable_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof TableExistsException) {
-                        result.ouch4 = (TableExistsException) e;
-                        result.setOuch4IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof TableExistsException) {
+              result.ouch4 = (TableExistsException) e;
+              result.setOuch4IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12271,7 +12443,7 @@
         return false;
       }
 
-      public void start(I iface, renameTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, renameTable_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.renameTable(args.login, args.oldTableName, args.newTableName,resultHandler);
       }
     }
@@ -12285,50 +12457,56 @@
         return new setLocalityGroups_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             setLocalityGroups_result result = new setLocalityGroups_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             setLocalityGroups_result result = new setLocalityGroups_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12337,7 +12515,7 @@
         return false;
       }
 
-      public void start(I iface, setLocalityGroups_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, setLocalityGroups_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.setLocalityGroups(args.login, args.tableName, args.groups,resultHandler);
       }
     }
@@ -12351,50 +12529,56 @@
         return new setTableProperty_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             setTableProperty_result result = new setTableProperty_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             setTableProperty_result result = new setTableProperty_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12403,12 +12587,12 @@
         return false;
       }
 
-      public void start(I iface, setTableProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, setTableProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.setTableProperty(args.login, args.tableName, args.property, args.value,resultHandler);
       }
     }
 
-    public static class splitRangeByTablets<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, splitRangeByTablets_args, Set<Range>> {
+    public static class splitRangeByTablets<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, splitRangeByTablets_args, java.util.Set<Range>> {
       public splitRangeByTablets() {
         super("splitRangeByTablets");
       }
@@ -12417,51 +12601,57 @@
         return new splitRangeByTablets_args();
       }
 
-      public AsyncMethodCallback<Set<Range>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Set<Range>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Set<Range>>() { 
-          public void onComplete(Set<Range> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Set<Range>>() { 
+          public void onComplete(java.util.Set<Range> o) {
             splitRangeByTablets_result result = new splitRangeByTablets_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             splitRangeByTablets_result result = new splitRangeByTablets_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12470,12 +12660,12 @@
         return false;
       }
 
-      public void start(I iface, splitRangeByTablets_args args, org.apache.thrift.async.AsyncMethodCallback<Set<Range>> resultHandler) throws TException {
+      public void start(I iface, splitRangeByTablets_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<Range>> resultHandler) throws org.apache.thrift.TException {
         iface.splitRangeByTablets(args.login, args.tableName, args.range, args.maxSplits,resultHandler);
       }
     }
 
-    public static class tableExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, tableExists_args, Boolean> {
+    public static class tableExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, tableExists_args, java.lang.Boolean> {
       public tableExists() {
         super("tableExists");
       }
@@ -12484,36 +12674,46 @@
         return new tableExists_args();
       }
 
-      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Boolean>() { 
-          public void onComplete(Boolean o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
+          public void onComplete(java.lang.Boolean o) {
             tableExists_result result = new tableExists_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             tableExists_result result = new tableExists_result();
-            {
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12522,12 +12722,12 @@
         return false;
       }
 
-      public void start(I iface, tableExists_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+      public void start(I iface, tableExists_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
         iface.tableExists(args.login, args.tableName,resultHandler);
       }
     }
 
-    public static class tableIdMap<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, tableIdMap_args, Map<String,String>> {
+    public static class tableIdMap<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, tableIdMap_args, java.util.Map<java.lang.String,java.lang.String>> {
       public tableIdMap() {
         super("tableIdMap");
       }
@@ -12536,35 +12736,45 @@
         return new tableIdMap_args();
       }
 
-      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.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) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.lang.String> o) {
             tableIdMap_result result = new tableIdMap_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             tableIdMap_result result = new tableIdMap_result();
-            {
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12573,12 +12783,12 @@
         return false;
       }
 
-      public void start(I iface, tableIdMap_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
+      public void start(I iface, tableIdMap_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException {
         iface.tableIdMap(args.login,resultHandler);
       }
     }
 
-    public static class testTableClassLoad<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, testTableClassLoad_args, Boolean> {
+    public static class testTableClassLoad<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, testTableClassLoad_args, java.lang.Boolean> {
       public testTableClassLoad() {
         super("testTableClassLoad");
       }
@@ -12587,52 +12797,58 @@
         return new testTableClassLoad_args();
       }
 
-      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Boolean>() { 
-          public void onComplete(Boolean o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
+          public void onComplete(java.lang.Boolean o) {
             testTableClassLoad_result result = new testTableClassLoad_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             testTableClassLoad_result result = new testTableClassLoad_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12641,7 +12857,7 @@
         return false;
       }
 
-      public void start(I iface, testTableClassLoad_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+      public void start(I iface, testTableClassLoad_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
         iface.testTableClassLoad(args.login, args.tableName, args.className, args.asTypeName,resultHandler);
       }
     }
@@ -12655,45 +12871,52 @@
         return new pingTabletServer_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             pingTabletServer_result result = new pingTabletServer_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             pingTabletServer_result result = new pingTabletServer_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12702,12 +12925,12 @@
         return false;
       }
 
-      public void start(I iface, pingTabletServer_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, pingTabletServer_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.pingTabletServer(args.login, args.tserver,resultHandler);
       }
     }
 
-    public static class getActiveScans<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getActiveScans_args, List<ActiveScan>> {
+    public static class getActiveScans<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getActiveScans_args, java.util.List<ActiveScan>> {
       public getActiveScans() {
         super("getActiveScans");
       }
@@ -12716,46 +12939,53 @@
         return new getActiveScans_args();
       }
 
-      public AsyncMethodCallback<List<ActiveScan>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveScan>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<List<ActiveScan>>() { 
-          public void onComplete(List<ActiveScan> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveScan>>() { 
+          public void onComplete(java.util.List<ActiveScan> o) {
             getActiveScans_result result = new getActiveScans_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getActiveScans_result result = new getActiveScans_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12764,12 +12994,12 @@
         return false;
       }
 
-      public void start(I iface, getActiveScans_args args, org.apache.thrift.async.AsyncMethodCallback<List<ActiveScan>> resultHandler) throws TException {
+      public void start(I iface, getActiveScans_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveScan>> resultHandler) throws org.apache.thrift.TException {
         iface.getActiveScans(args.login, args.tserver,resultHandler);
       }
     }
 
-    public static class getActiveCompactions<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getActiveCompactions_args, List<ActiveCompaction>> {
+    public static class getActiveCompactions<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getActiveCompactions_args, java.util.List<ActiveCompaction>> {
       public getActiveCompactions() {
         super("getActiveCompactions");
       }
@@ -12778,46 +13008,53 @@
         return new getActiveCompactions_args();
       }
 
-      public AsyncMethodCallback<List<ActiveCompaction>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveCompaction>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<List<ActiveCompaction>>() { 
-          public void onComplete(List<ActiveCompaction> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveCompaction>>() { 
+          public void onComplete(java.util.List<ActiveCompaction> o) {
             getActiveCompactions_result result = new getActiveCompactions_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getActiveCompactions_result result = new getActiveCompactions_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12826,12 +13063,12 @@
         return false;
       }
 
-      public void start(I iface, getActiveCompactions_args args, org.apache.thrift.async.AsyncMethodCallback<List<ActiveCompaction>> resultHandler) throws TException {
+      public void start(I iface, getActiveCompactions_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<ActiveCompaction>> resultHandler) throws org.apache.thrift.TException {
         iface.getActiveCompactions(args.login, args.tserver,resultHandler);
       }
     }
 
-    public static class getSiteConfiguration<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getSiteConfiguration_args, Map<String,String>> {
+    public static class getSiteConfiguration<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getSiteConfiguration_args, java.util.Map<java.lang.String,java.lang.String>> {
       public getSiteConfiguration() {
         super("getSiteConfiguration");
       }
@@ -12840,46 +13077,53 @@
         return new getSiteConfiguration_args();
       }
 
-      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.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) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.lang.String> o) {
             getSiteConfiguration_result result = new getSiteConfiguration_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getSiteConfiguration_result result = new getSiteConfiguration_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12888,12 +13132,12 @@
         return false;
       }
 
-      public void start(I iface, getSiteConfiguration_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
+      public void start(I iface, getSiteConfiguration_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException {
         iface.getSiteConfiguration(args.login,resultHandler);
       }
     }
 
-    public static class getSystemConfiguration<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getSystemConfiguration_args, Map<String,String>> {
+    public static class getSystemConfiguration<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getSystemConfiguration_args, java.util.Map<java.lang.String,java.lang.String>> {
       public getSystemConfiguration() {
         super("getSystemConfiguration");
       }
@@ -12902,46 +13146,53 @@
         return new getSystemConfiguration_args();
       }
 
-      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.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) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.lang.String> o) {
             getSystemConfiguration_result result = new getSystemConfiguration_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getSystemConfiguration_result result = new getSystemConfiguration_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -12950,12 +13201,12 @@
         return false;
       }
 
-      public void start(I iface, getSystemConfiguration_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
+      public void start(I iface, getSystemConfiguration_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException {
         iface.getSystemConfiguration(args.login,resultHandler);
       }
     }
 
-    public static class getTabletServers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getTabletServers_args, List<String>> {
+    public static class getTabletServers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getTabletServers_args, java.util.List<java.lang.String>> {
       public getTabletServers() {
         super("getTabletServers");
       }
@@ -12964,35 +13215,45 @@
         return new getTabletServers_args();
       }
 
-      public AsyncMethodCallback<List<String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<List<String>>() { 
-          public void onComplete(List<String> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>>() { 
+          public void onComplete(java.util.List<java.lang.String> o) {
             getTabletServers_result result = new getTabletServers_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getTabletServers_result result = new getTabletServers_result();
-            {
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13001,7 +13262,7 @@
         return false;
       }
 
-      public void start(I iface, getTabletServers_args args, org.apache.thrift.async.AsyncMethodCallback<List<String>> resultHandler) throws TException {
+      public void start(I iface, getTabletServers_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> resultHandler) throws org.apache.thrift.TException {
         iface.getTabletServers(args.login,resultHandler);
       }
     }
@@ -13015,45 +13276,52 @@
         return new removeProperty_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             removeProperty_result result = new removeProperty_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             removeProperty_result result = new removeProperty_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13062,7 +13330,7 @@
         return false;
       }
 
-      public void start(I iface, removeProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, removeProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.removeProperty(args.login, args.property,resultHandler);
       }
     }
@@ -13076,45 +13344,52 @@
         return new setProperty_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             setProperty_result result = new setProperty_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             setProperty_result result = new setProperty_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13123,12 +13398,12 @@
         return false;
       }
 
-      public void start(I iface, setProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, setProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.setProperty(args.login, args.property, args.value,resultHandler);
       }
     }
 
-    public static class testClassLoad<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, testClassLoad_args, Boolean> {
+    public static class testClassLoad<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, testClassLoad_args, java.lang.Boolean> {
       public testClassLoad() {
         super("testClassLoad");
       }
@@ -13137,47 +13412,54 @@
         return new testClassLoad_args();
       }
 
-      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Boolean>() { 
-          public void onComplete(Boolean o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
+          public void onComplete(java.lang.Boolean o) {
             testClassLoad_result result = new testClassLoad_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             testClassLoad_result result = new testClassLoad_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13186,12 +13468,12 @@
         return false;
       }
 
-      public void start(I iface, testClassLoad_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+      public void start(I iface, testClassLoad_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
         iface.testClassLoad(args.login, args.className, args.asTypeName,resultHandler);
       }
     }
 
-    public static class authenticateUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, authenticateUser_args, Boolean> {
+    public static class authenticateUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, authenticateUser_args, java.lang.Boolean> {
       public authenticateUser() {
         super("authenticateUser");
       }
@@ -13200,47 +13482,54 @@
         return new authenticateUser_args();
       }
 
-      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Boolean>() { 
-          public void onComplete(Boolean o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
+          public void onComplete(java.lang.Boolean o) {
             authenticateUser_result result = new authenticateUser_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             authenticateUser_result result = new authenticateUser_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13249,7 +13538,7 @@
         return false;
       }
 
-      public void start(I iface, authenticateUser_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+      public void start(I iface, authenticateUser_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
         iface.authenticateUser(args.login, args.user, args.properties,resultHandler);
       }
     }
@@ -13263,45 +13552,52 @@
         return new changeUserAuthorizations_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             changeUserAuthorizations_result result = new changeUserAuthorizations_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             changeUserAuthorizations_result result = new changeUserAuthorizations_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13310,7 +13606,7 @@
         return false;
       }
 
-      public void start(I iface, changeUserAuthorizations_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, changeUserAuthorizations_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.changeUserAuthorizations(args.login, args.user, args.authorizations,resultHandler);
       }
     }
@@ -13324,45 +13620,52 @@
         return new changeLocalUserPassword_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             changeLocalUserPassword_result result = new changeLocalUserPassword_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             changeLocalUserPassword_result result = new changeLocalUserPassword_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13371,7 +13674,7 @@
         return false;
       }
 
-      public void start(I iface, changeLocalUserPassword_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, changeLocalUserPassword_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.changeLocalUserPassword(args.login, args.user, args.password,resultHandler);
       }
     }
@@ -13385,45 +13688,52 @@
         return new createLocalUser_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             createLocalUser_result result = new createLocalUser_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             createLocalUser_result result = new createLocalUser_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13432,7 +13742,7 @@
         return false;
       }
 
-      public void start(I iface, createLocalUser_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, createLocalUser_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.createLocalUser(args.login, args.user, args.password,resultHandler);
       }
     }
@@ -13446,45 +13756,52 @@
         return new dropLocalUser_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             dropLocalUser_result result = new dropLocalUser_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             dropLocalUser_result result = new dropLocalUser_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13493,12 +13810,12 @@
         return false;
       }
 
-      public void start(I iface, dropLocalUser_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, dropLocalUser_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.dropLocalUser(args.login, args.user,resultHandler);
       }
     }
 
-    public static class getUserAuthorizations<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getUserAuthorizations_args, List<ByteBuffer>> {
+    public static class getUserAuthorizations<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getUserAuthorizations_args, java.util.List<java.nio.ByteBuffer>> {
       public getUserAuthorizations() {
         super("getUserAuthorizations");
       }
@@ -13507,46 +13824,53 @@
         return new getUserAuthorizations_args();
       }
 
-      public AsyncMethodCallback<List<ByteBuffer>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<List<ByteBuffer>>() { 
-          public void onComplete(List<ByteBuffer> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>>() { 
+          public void onComplete(java.util.List<java.nio.ByteBuffer> o) {
             getUserAuthorizations_result result = new getUserAuthorizations_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getUserAuthorizations_result result = new getUserAuthorizations_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13555,7 +13879,7 @@
         return false;
       }
 
-      public void start(I iface, getUserAuthorizations_args args, org.apache.thrift.async.AsyncMethodCallback<List<ByteBuffer>> resultHandler) throws TException {
+      public void start(I iface, getUserAuthorizations_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.nio.ByteBuffer>> resultHandler) throws org.apache.thrift.TException {
         iface.getUserAuthorizations(args.login, args.user,resultHandler);
       }
     }
@@ -13569,45 +13893,52 @@
         return new grantSystemPermission_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             grantSystemPermission_result result = new grantSystemPermission_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             grantSystemPermission_result result = new grantSystemPermission_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13616,7 +13947,7 @@
         return false;
       }
 
-      public void start(I iface, grantSystemPermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, grantSystemPermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.grantSystemPermission(args.login, args.user, args.perm,resultHandler);
       }
     }
@@ -13630,50 +13961,56 @@
         return new grantTablePermission_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             grantTablePermission_result result = new grantTablePermission_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             grantTablePermission_result result = new grantTablePermission_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13682,12 +14019,12 @@
         return false;
       }
 
-      public void start(I iface, grantTablePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, grantTablePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.grantTablePermission(args.login, args.user, args.table, args.perm,resultHandler);
       }
     }
 
-    public static class hasSystemPermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, hasSystemPermission_args, Boolean> {
+    public static class hasSystemPermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, hasSystemPermission_args, java.lang.Boolean> {
       public hasSystemPermission() {
         super("hasSystemPermission");
       }
@@ -13696,47 +14033,54 @@
         return new hasSystemPermission_args();
       }
 
-      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Boolean>() { 
-          public void onComplete(Boolean o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
+          public void onComplete(java.lang.Boolean o) {
             hasSystemPermission_result result = new hasSystemPermission_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             hasSystemPermission_result result = new hasSystemPermission_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13745,12 +14089,12 @@
         return false;
       }
 
-      public void start(I iface, hasSystemPermission_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+      public void start(I iface, hasSystemPermission_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
         iface.hasSystemPermission(args.login, args.user, args.perm,resultHandler);
       }
     }
 
-    public static class hasTablePermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, hasTablePermission_args, Boolean> {
+    public static class hasTablePermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, hasTablePermission_args, java.lang.Boolean> {
       public hasTablePermission() {
         super("hasTablePermission");
       }
@@ -13759,52 +14103,58 @@
         return new hasTablePermission_args();
       }
 
-      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Boolean>() { 
-          public void onComplete(Boolean o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
+          public void onComplete(java.lang.Boolean o) {
             hasTablePermission_result result = new hasTablePermission_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             hasTablePermission_result result = new hasTablePermission_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13813,12 +14163,12 @@
         return false;
       }
 
-      public void start(I iface, hasTablePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+      public void start(I iface, hasTablePermission_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
         iface.hasTablePermission(args.login, args.user, args.table, args.perm,resultHandler);
       }
     }
 
-    public static class listLocalUsers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listLocalUsers_args, Set<String>> {
+    public static class listLocalUsers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listLocalUsers_args, java.util.Set<java.lang.String>> {
       public listLocalUsers() {
         super("listLocalUsers");
       }
@@ -13827,51 +14177,57 @@
         return new listLocalUsers_args();
       }
 
-      public AsyncMethodCallback<Set<String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Set<String>>() { 
-          public void onComplete(Set<String> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>>() { 
+          public void onComplete(java.util.Set<java.lang.String> o) {
             listLocalUsers_result result = new listLocalUsers_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             listLocalUsers_result result = new listLocalUsers_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13880,7 +14236,7 @@
         return false;
       }
 
-      public void start(I iface, listLocalUsers_args args, org.apache.thrift.async.AsyncMethodCallback<Set<String>> resultHandler) throws TException {
+      public void start(I iface, listLocalUsers_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Set<java.lang.String>> resultHandler) throws org.apache.thrift.TException {
         iface.listLocalUsers(args.login,resultHandler);
       }
     }
@@ -13894,45 +14250,52 @@
         return new revokeSystemPermission_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             revokeSystemPermission_result result = new revokeSystemPermission_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             revokeSystemPermission_result result = new revokeSystemPermission_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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -13941,7 +14304,7 @@
         return false;
       }
 
-      public void start(I iface, revokeSystemPermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, revokeSystemPermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.revokeSystemPermission(args.login, args.user, args.perm,resultHandler);
       }
     }
@@ -13955,50 +14318,56 @@
         return new revokeTablePermission_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             revokeTablePermission_result result = new revokeTablePermission_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             revokeTablePermission_result result = new revokeTablePermission_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14007,7 +14376,7 @@
         return false;
       }
 
-      public void start(I iface, revokeTablePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, revokeTablePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.revokeTablePermission(args.login, args.user, args.table, args.perm,resultHandler);
       }
     }
@@ -14021,45 +14390,52 @@
         return new grantNamespacePermission_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14068,12 +14444,12 @@
         return false;
       }
 
-      public void start(I iface, grantNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, grantNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.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 static class hasNamespacePermission<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, hasNamespacePermission_args, java.lang.Boolean> {
       public hasNamespacePermission() {
         super("hasNamespacePermission");
       }
@@ -14082,47 +14458,54 @@
         return new hasNamespacePermission_args();
       }
 
-      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Boolean>() { 
-          public void onComplete(Boolean o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
+          public void onComplete(java.lang.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14131,7 +14514,7 @@
         return false;
       }
 
-      public void start(I iface, hasNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+      public void start(I iface, hasNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
         iface.hasNamespacePermission(args.login, args.user, args.namespaceName, args.perm,resultHandler);
       }
     }
@@ -14145,45 +14528,52 @@
         return new revokeNamespacePermission_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14192,12 +14582,12 @@
         return false;
       }
 
-      public void start(I iface, revokeNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, revokeNamespacePermission_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.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 static class createBatchScanner<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createBatchScanner_args, java.lang.String> {
       public createBatchScanner() {
         super("createBatchScanner");
       }
@@ -14206,51 +14596,57 @@
         return new createBatchScanner_args();
       }
 
-      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<String>() { 
-          public void onComplete(String o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
+          public void onComplete(java.lang.String o) {
             createBatchScanner_result result = new createBatchScanner_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             createBatchScanner_result result = new createBatchScanner_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14259,12 +14655,12 @@
         return false;
       }
 
-      public void start(I iface, createBatchScanner_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
+      public void start(I iface, createBatchScanner_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
         iface.createBatchScanner(args.login, args.tableName, args.options,resultHandler);
       }
     }
 
-    public static class createScanner<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createScanner_args, String> {
+    public static class createScanner<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createScanner_args, java.lang.String> {
       public createScanner() {
         super("createScanner");
       }
@@ -14273,51 +14669,57 @@
         return new createScanner_args();
       }
 
-      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<String>() { 
-          public void onComplete(String o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
+          public void onComplete(java.lang.String o) {
             createScanner_result result = new createScanner_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             createScanner_result result = new createScanner_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14326,12 +14728,12 @@
         return false;
       }
 
-      public void start(I iface, createScanner_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
+      public void start(I iface, createScanner_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
         iface.createScanner(args.login, args.tableName, args.options,resultHandler);
       }
     }
 
-    public static class hasNext<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, hasNext_args, Boolean> {
+    public static class hasNext<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, hasNext_args, java.lang.Boolean> {
       public hasNext() {
         super("hasNext");
       }
@@ -14340,42 +14742,50 @@
         return new hasNext_args();
       }
 
-      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Boolean>() { 
-          public void onComplete(Boolean o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
+          public void onComplete(java.lang.Boolean o) {
             hasNext_result result = new hasNext_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             hasNext_result result = new hasNext_result();
             if (e instanceof UnknownScanner) {
-                        result.ouch1 = (UnknownScanner) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (UnknownScanner) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14384,7 +14794,7 @@
         return false;
       }
 
-      public void start(I iface, hasNext_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+      public void start(I iface, hasNext_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
         iface.hasNext(args.scanner,resultHandler);
       }
     }
@@ -14398,51 +14808,57 @@
         return new nextEntry_args();
       }
 
-      public AsyncMethodCallback<KeyValueAndPeek> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<KeyValueAndPeek> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<KeyValueAndPeek>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<KeyValueAndPeek>() { 
           public void onComplete(KeyValueAndPeek o) {
             nextEntry_result result = new nextEntry_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             nextEntry_result result = new nextEntry_result();
             if (e instanceof NoMoreEntriesException) {
-                        result.ouch1 = (NoMoreEntriesException) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof UnknownScanner) {
-                        result.ouch2 = (UnknownScanner) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloSecurityException) {
-                        result.ouch3 = (AccumuloSecurityException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (NoMoreEntriesException) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof UnknownScanner) {
+              result.ouch2 = (UnknownScanner) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloSecurityException) {
+              result.ouch3 = (AccumuloSecurityException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14451,7 +14867,7 @@
         return false;
       }
 
-      public void start(I iface, nextEntry_args args, org.apache.thrift.async.AsyncMethodCallback<KeyValueAndPeek> resultHandler) throws TException {
+      public void start(I iface, nextEntry_args args, org.apache.thrift.async.AsyncMethodCallback<KeyValueAndPeek> resultHandler) throws org.apache.thrift.TException {
         iface.nextEntry(args.scanner,resultHandler);
       }
     }
@@ -14465,51 +14881,57 @@
         return new nextK_args();
       }
 
-      public AsyncMethodCallback<ScanResult> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<ScanResult> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<ScanResult>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<ScanResult>() { 
           public void onComplete(ScanResult o) {
             nextK_result result = new nextK_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             nextK_result result = new nextK_result();
             if (e instanceof NoMoreEntriesException) {
-                        result.ouch1 = (NoMoreEntriesException) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof UnknownScanner) {
-                        result.ouch2 = (UnknownScanner) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloSecurityException) {
-                        result.ouch3 = (AccumuloSecurityException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (NoMoreEntriesException) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof UnknownScanner) {
+              result.ouch2 = (UnknownScanner) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloSecurityException) {
+              result.ouch3 = (AccumuloSecurityException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14518,7 +14940,7 @@
         return false;
       }
 
-      public void start(I iface, nextK_args args, org.apache.thrift.async.AsyncMethodCallback<ScanResult> resultHandler) throws TException {
+      public void start(I iface, nextK_args args, org.apache.thrift.async.AsyncMethodCallback<ScanResult> resultHandler) throws org.apache.thrift.TException {
         iface.nextK(args.scanner, args.k,resultHandler);
       }
     }
@@ -14532,40 +14954,48 @@
         return new closeScanner_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             closeScanner_result result = new closeScanner_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             closeScanner_result result = new closeScanner_result();
             if (e instanceof UnknownScanner) {
-                        result.ouch1 = (UnknownScanner) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (UnknownScanner) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14574,7 +15004,7 @@
         return false;
       }
 
-      public void start(I iface, closeScanner_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, closeScanner_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.closeScanner(args.scanner,resultHandler);
       }
     }
@@ -14588,55 +15018,60 @@
         return new updateAndFlush_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             updateAndFlush_result result = new updateAndFlush_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             updateAndFlush_result result = new updateAndFlush_result();
             if (e instanceof AccumuloException) {
-                        result.outch1 = (AccumuloException) e;
-                        result.setOutch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloSecurityException) {
-                        result.ouch2 = (AccumuloSecurityException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof MutationsRejectedException) {
-                        result.ouch4 = (MutationsRejectedException) e;
-                        result.setOuch4IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.outch1 = (AccumuloException) e;
+              result.setOutch1IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloSecurityException) {
+              result.ouch2 = (AccumuloSecurityException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof MutationsRejectedException) {
+              result.ouch4 = (MutationsRejectedException) e;
+              result.setOuch4IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14645,12 +15080,12 @@
         return false;
       }
 
-      public void start(I iface, updateAndFlush_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, updateAndFlush_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.updateAndFlush(args.login, args.tableName, args.cells,resultHandler);
       }
     }
 
-    public static class createWriter<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createWriter_args, String> {
+    public static class createWriter<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createWriter_args, java.lang.String> {
       public createWriter() {
         super("createWriter");
       }
@@ -14659,51 +15094,57 @@
         return new createWriter_args();
       }
 
-      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<String>() { 
-          public void onComplete(String o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
+          public void onComplete(java.lang.String o) {
             createWriter_result result = new createWriter_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             createWriter_result result = new createWriter_result();
             if (e instanceof AccumuloException) {
-                        result.outch1 = (AccumuloException) e;
-                        result.setOutch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloSecurityException) {
-                        result.ouch2 = (AccumuloSecurityException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.outch1 = (AccumuloException) e;
+              result.setOutch1IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloSecurityException) {
+              result.ouch2 = (AccumuloSecurityException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14712,7 +15153,7 @@
         return false;
       }
 
-      public void start(I iface, createWriter_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
+      public void start(I iface, createWriter_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
         iface.createWriter(args.login, args.tableName, args.opts,resultHandler);
       }
     }
@@ -14726,12 +15167,18 @@
         return new update_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+            } else {
+              _LOGGER.error("Exception inside oneway handler", e);
+            }
           }
         };
       }
@@ -14740,7 +15187,7 @@
         return true;
       }
 
-      public void start(I iface, update_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, update_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.update(args.writer, args.cells,resultHandler);
       }
     }
@@ -14754,45 +15201,52 @@
         return new flush_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             flush_result result = new flush_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             flush_result result = new flush_result();
             if (e instanceof UnknownWriter) {
-                        result.ouch1 = (UnknownWriter) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof MutationsRejectedException) {
-                        result.ouch2 = (MutationsRejectedException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (UnknownWriter) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof MutationsRejectedException) {
+              result.ouch2 = (MutationsRejectedException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14801,7 +15255,7 @@
         return false;
       }
 
-      public void start(I iface, flush_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, flush_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.flush(args.writer,resultHandler);
       }
     }
@@ -14815,45 +15269,52 @@
         return new closeWriter_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             closeWriter_result result = new closeWriter_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             closeWriter_result result = new closeWriter_result();
             if (e instanceof UnknownWriter) {
-                        result.ouch1 = (UnknownWriter) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof MutationsRejectedException) {
-                        result.ouch2 = (MutationsRejectedException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (UnknownWriter) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof MutationsRejectedException) {
+              result.ouch2 = (MutationsRejectedException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14862,7 +15323,7 @@
         return false;
       }
 
-      public void start(I iface, closeWriter_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, closeWriter_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.closeWriter(args.writer,resultHandler);
       }
     }
@@ -14876,51 +15337,57 @@
         return new updateRowConditionally_args();
       }
 
-      public AsyncMethodCallback<ConditionalStatus> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<ConditionalStatus> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<ConditionalStatus>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<ConditionalStatus>() { 
           public void onComplete(ConditionalStatus o) {
             updateRowConditionally_result result = new updateRowConditionally_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             updateRowConditionally_result result = new updateRowConditionally_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14929,12 +15396,12 @@
         return false;
       }
 
-      public void start(I iface, updateRowConditionally_args args, org.apache.thrift.async.AsyncMethodCallback<ConditionalStatus> resultHandler) throws TException {
+      public void start(I iface, updateRowConditionally_args args, org.apache.thrift.async.AsyncMethodCallback<ConditionalStatus> resultHandler) throws org.apache.thrift.TException {
         iface.updateRowConditionally(args.login, args.tableName, args.row, args.updates,resultHandler);
       }
     }
 
-    public static class createConditionalWriter<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createConditionalWriter_args, String> {
+    public static class createConditionalWriter<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createConditionalWriter_args, java.lang.String> {
       public createConditionalWriter() {
         super("createConditionalWriter");
       }
@@ -14943,51 +15410,57 @@
         return new createConditionalWriter_args();
       }
 
-      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<String>() { 
-          public void onComplete(String o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
+          public void onComplete(java.lang.String o) {
             createConditionalWriter_result result = new createConditionalWriter_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             createConditionalWriter_result result = new createConditionalWriter_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 TableNotFoundException) {
-                        result.ouch3 = (TableNotFoundException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              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 TableNotFoundException) {
+              result.ouch3 = (TableNotFoundException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -14996,12 +15469,12 @@
         return false;
       }
 
-      public void start(I iface, createConditionalWriter_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
+      public void start(I iface, createConditionalWriter_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
         iface.createConditionalWriter(args.login, args.tableName, args.options,resultHandler);
       }
     }
 
-    public static class updateRowsConditionally<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateRowsConditionally_args, Map<ByteBuffer,ConditionalStatus>> {
+    public static class updateRowsConditionally<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateRowsConditionally_args, java.util.Map<java.nio.ByteBuffer,ConditionalStatus>> {
       public updateRowsConditionally() {
         super("updateRowsConditionally");
       }
@@ -15010,51 +15483,57 @@
         return new updateRowsConditionally_args();
       }
 
-      public AsyncMethodCallback<Map<ByteBuffer,ConditionalStatus>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.nio.ByteBuffer,ConditionalStatus>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Map<ByteBuffer,ConditionalStatus>>() { 
-          public void onComplete(Map<ByteBuffer,ConditionalStatus> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.nio.ByteBuffer,ConditionalStatus>>() { 
+          public void onComplete(java.util.Map<java.nio.ByteBuffer,ConditionalStatus> o) {
             updateRowsConditionally_result result = new updateRowsConditionally_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             updateRowsConditionally_result result = new updateRowsConditionally_result();
             if (e instanceof UnknownWriter) {
-                        result.ouch1 = (UnknownWriter) e;
-                        result.setOuch1IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloException) {
-                        result.ouch2 = (AccumuloException) e;
-                        result.setOuch2IsSet(true);
-                        msg = result;
-            }
-            else             if (e instanceof AccumuloSecurityException) {
-                        result.ouch3 = (AccumuloSecurityException) e;
-                        result.setOuch3IsSet(true);
-                        msg = result;
-            }
-             else 
-            {
+              result.ouch1 = (UnknownWriter) e;
+              result.setOuch1IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloException) {
+              result.ouch2 = (AccumuloException) e;
+              result.setOuch2IsSet(true);
+              msg = result;
+            } else if (e instanceof AccumuloSecurityException) {
+              result.ouch3 = (AccumuloSecurityException) e;
+              result.setOuch3IsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15063,7 +15542,7 @@
         return false;
       }
 
-      public void start(I iface, updateRowsConditionally_args args, org.apache.thrift.async.AsyncMethodCallback<Map<ByteBuffer,ConditionalStatus>> resultHandler) throws TException {
+      public void start(I iface, updateRowsConditionally_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.nio.ByteBuffer,ConditionalStatus>> resultHandler) throws org.apache.thrift.TException {
         iface.updateRowsConditionally(args.conditionalWriter, args.updates,resultHandler);
       }
     }
@@ -15077,34 +15556,44 @@
         return new closeConditionalWriter_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
           public void onComplete(Void o) {
             closeConditionalWriter_result result = new closeConditionalWriter_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             closeConditionalWriter_result result = new closeConditionalWriter_result();
-            {
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15113,7 +15602,7 @@
         return false;
       }
 
-      public void start(I iface, closeConditionalWriter_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, closeConditionalWriter_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.closeConditionalWriter(args.conditionalWriter,resultHandler);
       }
     }
@@ -15127,35 +15616,45 @@
         return new getRowRange_args();
       }
 
-      public AsyncMethodCallback<Range> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Range> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Range>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Range>() { 
           public void onComplete(Range o) {
             getRowRange_result result = new getRowRange_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getRowRange_result result = new getRowRange_result();
-            {
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15164,7 +15663,7 @@
         return false;
       }
 
-      public void start(I iface, getRowRange_args args, org.apache.thrift.async.AsyncMethodCallback<Range> resultHandler) throws TException {
+      public void start(I iface, getRowRange_args args, org.apache.thrift.async.AsyncMethodCallback<Range> resultHandler) throws org.apache.thrift.TException {
         iface.getRowRange(args.row,resultHandler);
       }
     }
@@ -15178,35 +15677,45 @@
         return new getFollowing_args();
       }
 
-      public AsyncMethodCallback<Key> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Key> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Key>() { 
+        return new org.apache.thrift.async.AsyncMethodCallback<Key>() { 
           public void onComplete(Key o) {
             getFollowing_result result = new getFollowing_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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             getFollowing_result result = new getFollowing_result();
-            {
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15215,12 +15724,12 @@
         return false;
       }
 
-      public void start(I iface, getFollowing_args args, org.apache.thrift.async.AsyncMethodCallback<Key> resultHandler) throws TException {
+      public void start(I iface, getFollowing_args args, org.apache.thrift.async.AsyncMethodCallback<Key> resultHandler) throws org.apache.thrift.TException {
         iface.getFollowing(args.key, args.part,resultHandler);
       }
     }
 
-    public static class systemNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, systemNamespace_args, String> {
+    public static class systemNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, systemNamespace_args, java.lang.String> {
       public systemNamespace() {
         super("systemNamespace");
       }
@@ -15229,35 +15738,45 @@
         return new systemNamespace_args();
       }
 
-      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<String>() { 
-          public void onComplete(String o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
+          public void onComplete(java.lang.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             systemNamespace_result result = new systemNamespace_result();
-            {
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15266,12 +15785,12 @@
         return false;
       }
 
-      public void start(I iface, systemNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
+      public void start(I iface, systemNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
         iface.systemNamespace(resultHandler);
       }
     }
 
-    public static class defaultNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, defaultNamespace_args, String> {
+    public static class defaultNamespace<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, defaultNamespace_args, java.lang.String> {
       public defaultNamespace() {
         super("defaultNamespace");
       }
@@ -15280,35 +15799,45 @@
         return new defaultNamespace_args();
       }
 
-      public AsyncMethodCallback<String> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<String>() { 
-          public void onComplete(String o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
+          public void onComplete(java.lang.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable msg;
             defaultNamespace_result result = new defaultNamespace_result();
-            {
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15317,12 +15846,12 @@
         return false;
       }
 
-      public void start(I iface, defaultNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws TException {
+      public void start(I iface, defaultNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
         iface.defaultNamespace(resultHandler);
       }
     }
 
-    public static class listNamespaces<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listNamespaces_args, List<String>> {
+    public static class listNamespaces<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listNamespaces_args, java.util.List<java.lang.String>> {
       public listNamespaces() {
         super("listNamespaces");
       }
@@ -15331,46 +15860,53 @@
         return new listNamespaces_args();
       }
 
-      public AsyncMethodCallback<List<String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<List<String>>() { 
-          public void onComplete(List<String> o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>>() { 
+          public void onComplete(java.util.List<java.lang.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15379,12 +15915,12 @@
         return false;
       }
 
-      public void start(I iface, listNamespaces_args args, org.apache.thrift.async.AsyncMethodCallback<List<String>> resultHandler) throws TException {
+      public void start(I iface, listNamespaces_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<java.lang.String>> resultHandler) throws org.apache.thrift.TException {
         iface.listNamespaces(args.login,resultHandler);
       }
     }
 
-    public static class namespaceExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, namespaceExists_args, Boolean> {
+    public static class namespaceExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, namespaceExists_args, java.lang.Boolean> {
       public namespaceExists() {
         super("namespaceExists");
       }
@@ -15393,47 +15929,54 @@
         return new namespaceExists_args();
       }
 
-      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Boolean>() { 
-          public void onComplete(Boolean o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
+          public void onComplete(java.lang.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15442,7 +15985,7 @@
         return false;
       }
 
-      public void start(I iface, namespaceExists_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+      public void start(I iface, namespaceExists_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
         iface.namespaceExists(args.login, args.namespaceName,resultHandler);
       }
     }
@@ -15456,50 +15999,56 @@
         return new createNamespace_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15508,7 +16057,7 @@
         return false;
       }
 
-      public void start(I iface, createNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, createNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.createNamespace(args.login, args.namespaceName,resultHandler);
       }
     }
@@ -15522,55 +16071,60 @@
         return new deleteNamespace_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15579,7 +16133,7 @@
         return false;
       }
 
-      public void start(I iface, deleteNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, deleteNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.deleteNamespace(args.login, args.namespaceName,resultHandler);
       }
     }
@@ -15593,55 +16147,60 @@
         return new renameNamespace_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15650,7 +16209,7 @@
         return false;
       }
 
-      public void start(I iface, renameNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, renameNamespace_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.renameNamespace(args.login, args.oldNamespaceName, args.newNamespaceName,resultHandler);
       }
     }
@@ -15664,50 +16223,56 @@
         return new setNamespaceProperty_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15716,7 +16281,7 @@
         return false;
       }
 
-      public void start(I iface, setNamespaceProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, setNamespaceProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.setNamespaceProperty(args.login, args.namespaceName, args.property, args.value,resultHandler);
       }
     }
@@ -15730,50 +16295,56 @@
         return new removeNamespaceProperty_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15782,12 +16353,12 @@
         return false;
       }
 
-      public void start(I iface, removeNamespaceProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, removeNamespaceProperty_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.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 static class getNamespaceProperties<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getNamespaceProperties_args, java.util.Map<java.lang.String,java.lang.String>> {
       public getNamespaceProperties() {
         super("getNamespaceProperties");
       }
@@ -15796,51 +16367,57 @@
         return new getNamespaceProperties_args();
       }
 
-      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.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) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.lang.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15849,12 +16426,12 @@
         return false;
       }
 
-      public void start(I iface, getNamespaceProperties_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
+      public void start(I iface, getNamespaceProperties_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.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 static class namespaceIdMap<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, namespaceIdMap_args, java.util.Map<java.lang.String,java.lang.String>> {
       public namespaceIdMap() {
         super("namespaceIdMap");
       }
@@ -15863,46 +16440,53 @@
         return new namespaceIdMap_args();
       }
 
-      public AsyncMethodCallback<Map<String,String>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.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) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.lang.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15911,7 +16495,7 @@
         return false;
       }
 
-      public void start(I iface, namespaceIdMap_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,String>> resultHandler) throws TException {
+      public void start(I iface, namespaceIdMap_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.String>> resultHandler) throws org.apache.thrift.TException {
         iface.namespaceIdMap(args.login,resultHandler);
       }
     }
@@ -15925,50 +16509,56 @@
         return new attachNamespaceIterator_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -15977,7 +16567,7 @@
         return false;
       }
 
-      public void start(I iface, attachNamespaceIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, attachNamespaceIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.attachNamespaceIterator(args.login, args.namespaceName, args.setting, args.scopes,resultHandler);
       }
     }
@@ -15991,50 +16581,56 @@
         return new removeNamespaceIterator_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -16043,7 +16639,7 @@
         return false;
       }
 
-      public void start(I iface, removeNamespaceIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, removeNamespaceIterator_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
         iface.removeNamespaceIterator(args.login, args.namespaceName, args.name, args.scopes,resultHandler);
       }
     }
@@ -16057,51 +16653,57 @@
         return new getNamespaceIteratorSetting_args();
       }
 
-      public AsyncMethodCallback<IteratorSetting> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<IteratorSetting>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -16110,12 +16712,12 @@
         return false;
       }
 
-      public void start(I iface, getNamespaceIteratorSetting_args args, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> resultHandler) throws TException {
+      public void start(I iface, getNamespaceIteratorSetting_args args, org.apache.thrift.async.AsyncMethodCallback<IteratorSetting> resultHandler) throws org.apache.thrift.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 static class listNamespaceIterators<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listNamespaceIterators_args, java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> {
       public listNamespaceIterators() {
         super("listNamespaceIterators");
       }
@@ -16124,51 +16726,57 @@
         return new listNamespaceIterators_args();
       }
 
-      public AsyncMethodCallback<Map<String,Set<IteratorScope>>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.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) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.util.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -16177,7 +16785,7 @@
         return false;
       }
 
-      public void start(I iface, listNamespaceIterators_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,Set<IteratorScope>>> resultHandler) throws TException {
+      public void start(I iface, listNamespaceIterators_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.util.Set<IteratorScope>>> resultHandler) throws org.apache.thrift.TException {
         iface.listNamespaceIterators(args.login, args.namespaceName,resultHandler);
       }
     }
@@ -16191,50 +16799,56 @@
         return new checkNamespaceIteratorConflicts_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -16243,12 +16857,12 @@
         return false;
       }
 
-      public void start(I iface, checkNamespaceIteratorConflicts_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, checkNamespaceIteratorConflicts_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.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 static class addNamespaceConstraint<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addNamespaceConstraint_args, java.lang.Integer> {
       public addNamespaceConstraint() {
         super("addNamespaceConstraint");
       }
@@ -16257,52 +16871,58 @@
         return new addNamespaceConstraint_args();
       }
 
-      public AsyncMethodCallback<Integer> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Integer>() { 
-          public void onComplete(Integer o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer>() { 
+          public void onComplete(java.lang.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -16311,7 +16931,7 @@
         return false;
       }
 
-      public void start(I iface, addNamespaceConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws TException {
+      public void start(I iface, addNamespaceConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
         iface.addNamespaceConstraint(args.login, args.namespaceName, args.constraintClassName,resultHandler);
       }
     }
@@ -16325,50 +16945,56 @@
         return new removeNamespaceConstraint_args();
       }
 
-      public AsyncMethodCallback<Void> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Void>() { 
+        return new org.apache.thrift.async.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -16377,12 +17003,12 @@
         return false;
       }
 
-      public void start(I iface, removeNamespaceConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws TException {
+      public void start(I iface, removeNamespaceConstraint_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.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 static class listNamespaceConstraints<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, listNamespaceConstraints_args, java.util.Map<java.lang.String,java.lang.Integer>> {
       public listNamespaceConstraints() {
         super("listNamespaceConstraints");
       }
@@ -16391,51 +17017,57 @@
         return new listNamespaceConstraints_args();
       }
 
-      public AsyncMethodCallback<Map<String,Integer>> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.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) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>>() { 
+          public void onComplete(java.util.Map<java.lang.String,java.lang.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -16444,12 +17076,12 @@
         return false;
       }
 
-      public void start(I iface, listNamespaceConstraints_args args, org.apache.thrift.async.AsyncMethodCallback<Map<String,Integer>> resultHandler) throws TException {
+      public void start(I iface, listNamespaceConstraints_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.Map<java.lang.String,java.lang.Integer>> resultHandler) throws org.apache.thrift.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 static class testNamespaceClassLoad<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, testNamespaceClassLoad_args, java.lang.Boolean> {
       public testNamespaceClassLoad() {
         super("testNamespaceClassLoad");
       }
@@ -16458,52 +17090,58 @@
         return new testNamespaceClassLoad_args();
       }
 
-      public AsyncMethodCallback<Boolean> getResultHandler(final AsyncFrameBuffer fb, final int seqid) {
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
         final org.apache.thrift.AsyncProcessFunction fcall = this;
-        return new AsyncMethodCallback<Boolean>() { 
-          public void onComplete(Boolean o) {
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
+          public void onComplete(java.lang.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);
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
             }
-            fb.close();
           }
-          public void onError(Exception e) {
+          public void onError(java.lang.Exception e) {
             byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
-            org.apache.thrift.TBase msg;
+            org.apache.thrift.TSerializable 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 
-            {
+              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 org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
               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());
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = 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);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
             }
-            fb.close();
           }
         };
       }
@@ -16512,7 +17150,7 @@
         return false;
       }
 
-      public void start(I iface, testNamespaceClassLoad_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws TException {
+      public void start(I iface, testNamespaceClassLoad_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
         iface.testNamespaceClassLoad(args.login, args.namespaceName, args.className, args.asTypeName,resultHandler);
       }
     }
@@ -16525,24 +17163,21 @@
     private static final org.apache.thrift.protocol.TField PRINCIPAL_FIELD_DESC = new org.apache.thrift.protocol.TField("principal", org.apache.thrift.protocol.TType.STRING, (short)1);
     private static final org.apache.thrift.protocol.TField LOGIN_PROPERTIES_FIELD_DESC = new org.apache.thrift.protocol.TField("loginProperties", org.apache.thrift.protocol.TType.MAP, (short)2);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new login_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new login_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new login_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new login_argsTupleSchemeFactory();
 
-    public String principal; // required
-    public Map<String,String> loginProperties; // required
+    public java.lang.String principal; // required
+    public java.util.Map<java.lang.String,java.lang.String> loginProperties; // 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 {
       PRINCIPAL((short)1, "principal"),
       LOGIN_PROPERTIES((short)2, "loginProperties");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -16567,21 +17202,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -16590,22 +17225,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.PRINCIPAL, new org.apache.thrift.meta_data.FieldMetaData("principal", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.LOGIN_PROPERTIES, new org.apache.thrift.meta_data.FieldMetaData("loginProperties", 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))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(login_args.class, metaDataMap);
     }
 
@@ -16613,8 +17248,8 @@
     }
 
     public login_args(
-      String principal,
-      Map<String,String> loginProperties)
+      java.lang.String principal,
+      java.util.Map<java.lang.String,java.lang.String> loginProperties)
     {
       this();
       this.principal = principal;
@@ -16629,7 +17264,7 @@
         this.principal = other.principal;
       }
       if (other.isSetLoginProperties()) {
-        Map<String,String> __this__loginProperties = new HashMap<String,String>(other.loginProperties);
+        java.util.Map<java.lang.String,java.lang.String> __this__loginProperties = new java.util.HashMap<java.lang.String,java.lang.String>(other.loginProperties);
         this.loginProperties = __this__loginProperties;
       }
     }
@@ -16644,11 +17279,11 @@
       this.loginProperties = null;
     }
 
-    public String getPrincipal() {
+    public java.lang.String getPrincipal() {
       return this.principal;
     }
 
-    public login_args setPrincipal(String principal) {
+    public login_args setPrincipal(java.lang.String principal) {
       this.principal = principal;
       return this;
     }
@@ -16672,18 +17307,18 @@
       return (this.loginProperties == null) ? 0 : this.loginProperties.size();
     }
 
-    public void putToLoginProperties(String key, String val) {
+    public void putToLoginProperties(java.lang.String key, java.lang.String val) {
       if (this.loginProperties == null) {
-        this.loginProperties = new HashMap<String,String>();
+        this.loginProperties = new java.util.HashMap<java.lang.String,java.lang.String>();
       }
       this.loginProperties.put(key, val);
     }
 
-    public Map<String,String> getLoginProperties() {
+    public java.util.Map<java.lang.String,java.lang.String> getLoginProperties() {
       return this.loginProperties;
     }
 
-    public login_args setLoginProperties(Map<String,String> loginProperties) {
+    public login_args setLoginProperties(java.util.Map<java.lang.String,java.lang.String> loginProperties) {
       this.loginProperties = loginProperties;
       return this;
     }
@@ -16703,13 +17338,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case PRINCIPAL:
         if (value == null) {
           unsetPrincipal();
         } else {
-          setPrincipal((String)value);
+          setPrincipal((java.lang.String)value);
         }
         break;
 
@@ -16717,14 +17352,14 @@
         if (value == null) {
           unsetLoginProperties();
         } else {
-          setLoginProperties((Map<String,String>)value);
+          setLoginProperties((java.util.Map<java.lang.String,java.lang.String>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case PRINCIPAL:
         return getPrincipal();
@@ -16733,13 +17368,13 @@
         return getLoginProperties();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -16748,11 +17383,11 @@
       case LOGIN_PROPERTIES:
         return isSetLoginProperties();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof login_args)
@@ -16763,6 +17398,8 @@
     public boolean equals(login_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_principal = true && this.isSetPrincipal();
       boolean that_present_principal = true && that.isSetPrincipal();
@@ -16787,19 +17424,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_principal = true && (isSetPrincipal());
-      list.add(present_principal);
-      if (present_principal)
-        list.add(principal);
+      hashCode = hashCode * 8191 + ((isSetPrincipal()) ? 131071 : 524287);
+      if (isSetPrincipal())
+        hashCode = hashCode * 8191 + principal.hashCode();
 
-      boolean present_loginProperties = true && (isSetLoginProperties());
-      list.add(present_loginProperties);
-      if (present_loginProperties)
-        list.add(loginProperties);
+      hashCode = hashCode * 8191 + ((isSetLoginProperties()) ? 131071 : 524287);
+      if (isSetLoginProperties())
+        hashCode = hashCode * 8191 + loginProperties.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -16810,7 +17445,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetPrincipal()).compareTo(other.isSetPrincipal());
+      lastComparison = java.lang.Boolean.valueOf(isSetPrincipal()).compareTo(other.isSetPrincipal());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -16820,7 +17455,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetLoginProperties()).compareTo(other.isSetLoginProperties());
+      lastComparison = java.lang.Boolean.valueOf(isSetLoginProperties()).compareTo(other.isSetLoginProperties());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -16838,16 +17473,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("login_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("login_args(");
       boolean first = true;
 
       sb.append("principal:");
@@ -16882,7 +17517,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -16890,13 +17525,13 @@
       }
     }
 
-    private static class login_argsStandardSchemeFactory implements SchemeFactory {
+    private static class login_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public login_argsStandardScheme getScheme() {
         return new login_argsStandardScheme();
       }
     }
 
-    private static class login_argsStandardScheme extends StandardScheme<login_args> {
+    private static class login_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<login_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, login_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -16920,9 +17555,9 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map164 = iprot.readMapBegin();
-                  struct.loginProperties = new HashMap<String,String>(2*_map164.size);
-                  String _key165;
-                  String _val166;
+                  struct.loginProperties = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map164.size);
+                  java.lang.String _key165;
+                  java.lang.String _val166;
                   for (int _i167 = 0; _i167 < _map164.size; ++_i167)
                   {
                     _key165 = iprot.readString();
@@ -16960,7 +17595,7 @@
           oprot.writeFieldBegin(LOGIN_PROPERTIES_FIELD_DESC);
           {
             oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.loginProperties.size()));
-            for (Map.Entry<String, String> _iter168 : struct.loginProperties.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter168 : struct.loginProperties.entrySet())
             {
               oprot.writeString(_iter168.getKey());
               oprot.writeString(_iter168.getValue());
@@ -16975,18 +17610,18 @@
 
     }
 
-    private static class login_argsTupleSchemeFactory implements SchemeFactory {
+    private static class login_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public login_argsTupleScheme getScheme() {
         return new login_argsTupleScheme();
       }
     }
 
-    private static class login_argsTupleScheme extends TupleScheme<login_args> {
+    private static class login_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<login_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, login_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetPrincipal()) {
           optionals.set(0);
         }
@@ -17000,7 +17635,7 @@
         if (struct.isSetLoginProperties()) {
           {
             oprot.writeI32(struct.loginProperties.size());
-            for (Map.Entry<String, String> _iter169 : struct.loginProperties.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter169 : struct.loginProperties.entrySet())
             {
               oprot.writeString(_iter169.getKey());
               oprot.writeString(_iter169.getValue());
@@ -17011,8 +17646,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, login_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.principal = iprot.readString();
           struct.setPrincipalIsSet(true);
@@ -17020,9 +17655,9 @@
         if (incoming.get(1)) {
           {
             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);
-            String _key171;
-            String _val172;
+            struct.loginProperties = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map170.size);
+            java.lang.String _key171;
+            java.lang.String _val172;
             for (int _i173 = 0; _i173 < _map170.size; ++_i173)
             {
               _key171 = iprot.readString();
@@ -17035,6 +17670,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class login_result implements org.apache.thrift.TBase<login_result, login_result._Fields>, java.io.Serializable, Cloneable, Comparable<login_result>   {
@@ -17043,13 +17681,10 @@
     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 org.apache.thrift.protocol.TField OUCH2_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch2", org.apache.thrift.protocol.TType.STRUCT, (short)1);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new login_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new login_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new login_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new login_resultTupleSchemeFactory();
 
-    public ByteBuffer success; // required
+    public java.nio.ByteBuffer success; // required
     public AccumuloSecurityException ouch2; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -17057,10 +17692,10 @@
       SUCCESS((short)0, "success"),
       OUCH2((short)1, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -17085,21 +17720,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -17108,20 +17743,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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          , true)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(login_result.class, metaDataMap);
     }
 
@@ -17129,7 +17764,7 @@
     }
 
     public login_result(
-      ByteBuffer success,
+      java.nio.ByteBuffer success,
       AccumuloSecurityException ouch2)
     {
       this();
@@ -17164,16 +17799,16 @@
       return success == null ? null : success.array();
     }
 
-    public ByteBuffer bufferForSuccess() {
+    public java.nio.ByteBuffer bufferForSuccess() {
       return org.apache.thrift.TBaseHelper.copyBinary(success);
     }
 
     public login_result setSuccess(byte[] success) {
-      this.success = success == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(success, success.length));
+      this.success = success == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(success.clone());
       return this;
     }
 
-    public login_result setSuccess(ByteBuffer success) {
+    public login_result setSuccess(java.nio.ByteBuffer success) {
       this.success = org.apache.thrift.TBaseHelper.copyBinary(success);
       return this;
     }
@@ -17217,13 +17852,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setSuccess((byte[])value);
+          } else {
+            setSuccess((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -17238,7 +17877,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -17247,13 +17886,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -17262,11 +17901,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof login_result)
@@ -17277,6 +17916,8 @@
     public boolean equals(login_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -17301,19 +17942,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -17324,7 +17963,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -17334,7 +17973,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -17352,16 +17991,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("login_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("login_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -17396,7 +18035,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -17404,13 +18043,13 @@
       }
     }
 
-    private static class login_resultStandardSchemeFactory implements SchemeFactory {
+    private static class login_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public login_resultStandardScheme getScheme() {
         return new login_resultStandardScheme();
       }
     }
 
-    private static class login_resultStandardScheme extends StandardScheme<login_result> {
+    private static class login_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<login_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, login_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -17470,18 +18109,18 @@
 
     }
 
-    private static class login_resultTupleSchemeFactory implements SchemeFactory {
+    private static class login_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public login_resultTupleScheme getScheme() {
         return new login_resultTupleScheme();
       }
     }
 
-    private static class login_resultTupleScheme extends TupleScheme<login_result> {
+    private static class login_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<login_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, login_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -17499,8 +18138,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, login_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.success = iprot.readBinary();
           struct.setSuccessIsSet(true);
@@ -17513,6 +18152,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class addConstraint_args implements org.apache.thrift.TBase<addConstraint_args, addConstraint_args._Fields>, java.io.Serializable, Cloneable, Comparable<addConstraint_args>   {
@@ -17522,15 +18164,12 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", 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 addConstraint_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new addConstraint_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addConstraint_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addConstraint_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public String constraintClassName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.lang.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 {
@@ -17538,10 +18177,10 @@
       TABLE_NAME((short)2, "tableName"),
       CONSTRAINT_CLASS_NAME((short)3, "constraintClassName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -17568,21 +18207,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -17591,22 +18230,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", 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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addConstraint_args.class, metaDataMap);
     }
 
@@ -17614,9 +18253,9 @@
     }
 
     public addConstraint_args(
-      ByteBuffer login,
-      String tableName,
-      String constraintClassName)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.lang.String constraintClassName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -17655,16 +18294,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public addConstraint_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public addConstraint_args setLogin(ByteBuffer login) {
+    public addConstraint_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -17684,11 +18323,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public addConstraint_args setTableName(String tableName) {
+    public addConstraint_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -17708,11 +18347,11 @@
       }
     }
 
-    public String getConstraintClassName() {
+    public java.lang.String getConstraintClassName() {
       return this.constraintClassName;
     }
 
-    public addConstraint_args setConstraintClassName(String constraintClassName) {
+    public addConstraint_args setConstraintClassName(java.lang.String constraintClassName) {
       this.constraintClassName = constraintClassName;
       return this;
     }
@@ -17732,13 +18371,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -17746,7 +18389,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -17754,14 +18397,14 @@
         if (value == null) {
           unsetConstraintClassName();
         } else {
-          setConstraintClassName((String)value);
+          setConstraintClassName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -17773,13 +18416,13 @@
         return getConstraintClassName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -17790,11 +18433,11 @@
       case CONSTRAINT_CLASS_NAME:
         return isSetConstraintClassName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof addConstraint_args)
@@ -17805,6 +18448,8 @@
     public boolean equals(addConstraint_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -17838,24 +18483,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_constraintClassName = true && (isSetConstraintClassName());
-      list.add(present_constraintClassName);
-      if (present_constraintClassName)
-        list.add(constraintClassName);
+      hashCode = hashCode * 8191 + ((isSetConstraintClassName()) ? 131071 : 524287);
+      if (isSetConstraintClassName())
+        hashCode = hashCode * 8191 + constraintClassName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -17866,7 +18508,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -17876,7 +18518,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -17886,7 +18528,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetConstraintClassName()).compareTo(other.isSetConstraintClassName());
+      lastComparison = java.lang.Boolean.valueOf(isSetConstraintClassName()).compareTo(other.isSetConstraintClassName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -17904,16 +18546,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("addConstraint_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("addConstraint_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -17956,7 +18598,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -17964,13 +18606,13 @@
       }
     }
 
-    private static class addConstraint_argsStandardSchemeFactory implements SchemeFactory {
+    private static class addConstraint_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addConstraint_argsStandardScheme getScheme() {
         return new addConstraint_argsStandardScheme();
       }
     }
 
-    private static class addConstraint_argsStandardScheme extends StandardScheme<addConstraint_args> {
+    private static class addConstraint_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<addConstraint_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, addConstraint_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -18042,18 +18684,18 @@
 
     }
 
-    private static class addConstraint_argsTupleSchemeFactory implements SchemeFactory {
+    private static class addConstraint_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addConstraint_argsTupleScheme getScheme() {
         return new addConstraint_argsTupleScheme();
       }
     }
 
-    private static class addConstraint_argsTupleScheme extends TupleScheme<addConstraint_args> {
+    private static class addConstraint_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<addConstraint_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, addConstraint_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -18077,8 +18719,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, addConstraint_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -18094,6 +18736,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class addConstraint_result implements org.apache.thrift.TBase<addConstraint_result, addConstraint_result._Fields>, java.io.Serializable, Cloneable, Comparable<addConstraint_result>   {
@@ -18104,11 +18749,8 @@
     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 addConstraint_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new addConstraint_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addConstraint_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addConstraint_resultTupleSchemeFactory();
 
     public int success; // required
     public AccumuloException ouch1; // required
@@ -18122,10 +18764,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -18154,21 +18796,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -18177,7 +18819,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -18185,18 +18827,18 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addConstraint_result.class, metaDataMap);
     }
 
@@ -18258,16 +18900,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public AccumuloException getOuch1() {
@@ -18342,13 +18984,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Integer)value);
+          setSuccess((java.lang.Integer)value);
         }
         break;
 
@@ -18379,7 +19021,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -18394,13 +19036,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -18413,11 +19055,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof addConstraint_result)
@@ -18428,6 +19070,8 @@
     public boolean equals(addConstraint_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -18470,29 +19114,23 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + success;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -18503,7 +19141,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -18513,7 +19151,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -18523,7 +19161,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -18533,7 +19171,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -18551,16 +19189,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("addConstraint_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("addConstraint_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -18607,7 +19245,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -18617,13 +19255,13 @@
       }
     }
 
-    private static class addConstraint_resultStandardSchemeFactory implements SchemeFactory {
+    private static class addConstraint_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addConstraint_resultStandardScheme getScheme() {
         return new addConstraint_resultStandardScheme();
       }
     }
 
-    private static class addConstraint_resultStandardScheme extends StandardScheme<addConstraint_result> {
+    private static class addConstraint_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<addConstraint_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, addConstraint_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -18711,18 +19349,18 @@
 
     }
 
-    private static class addConstraint_resultTupleSchemeFactory implements SchemeFactory {
+    private static class addConstraint_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addConstraint_resultTupleScheme getScheme() {
         return new addConstraint_resultTupleScheme();
       }
     }
 
-    private static class addConstraint_resultTupleScheme extends TupleScheme<addConstraint_result> {
+    private static class addConstraint_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<addConstraint_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, addConstraint_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -18752,8 +19390,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, addConstraint_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = iprot.readI32();
           struct.setSuccessIsSet(true);
@@ -18776,6 +19414,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class addSplits_args implements org.apache.thrift.TBase<addSplits_args, addSplits_args._Fields>, java.io.Serializable, Cloneable, Comparable<addSplits_args>   {
@@ -18785,15 +19426,12 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField SPLITS_FIELD_DESC = new org.apache.thrift.protocol.TField("splits", org.apache.thrift.protocol.TType.SET, (short)3);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new addSplits_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new addSplits_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addSplits_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addSplits_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public Set<ByteBuffer> splits; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.util.Set<java.nio.ByteBuffer> splits; // 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 {
@@ -18801,10 +19439,10 @@
       TABLE_NAME((short)2, "tableName"),
       SPLITS((short)3, "splits");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -18831,21 +19469,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -18854,15 +19492,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -18870,7 +19508,7 @@
       tmpMap.put(_Fields.SPLITS, new org.apache.thrift.meta_data.FieldMetaData("splits", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
               new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addSplits_args.class, metaDataMap);
     }
 
@@ -18878,9 +19516,9 @@
     }
 
     public addSplits_args(
-      ByteBuffer login,
-      String tableName,
-      Set<ByteBuffer> splits)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.util.Set<java.nio.ByteBuffer> splits)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -18899,7 +19537,7 @@
         this.tableName = other.tableName;
       }
       if (other.isSetSplits()) {
-        Set<ByteBuffer> __this__splits = new HashSet<ByteBuffer>(other.splits);
+        java.util.Set<java.nio.ByteBuffer> __this__splits = new java.util.HashSet<java.nio.ByteBuffer>(other.splits);
         this.splits = __this__splits;
       }
     }
@@ -18920,16 +19558,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public addSplits_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public addSplits_args setLogin(ByteBuffer login) {
+    public addSplits_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -18949,11 +19587,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public addSplits_args setTableName(String tableName) {
+    public addSplits_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -18977,22 +19615,22 @@
       return (this.splits == null) ? 0 : this.splits.size();
     }
 
-    public java.util.Iterator<ByteBuffer> getSplitsIterator() {
+    public java.util.Iterator<java.nio.ByteBuffer> getSplitsIterator() {
       return (this.splits == null) ? null : this.splits.iterator();
     }
 
-    public void addToSplits(ByteBuffer elem) {
+    public void addToSplits(java.nio.ByteBuffer elem) {
       if (this.splits == null) {
-        this.splits = new HashSet<ByteBuffer>();
+        this.splits = new java.util.HashSet<java.nio.ByteBuffer>();
       }
       this.splits.add(elem);
     }
 
-    public Set<ByteBuffer> getSplits() {
+    public java.util.Set<java.nio.ByteBuffer> getSplits() {
       return this.splits;
     }
 
-    public addSplits_args setSplits(Set<ByteBuffer> splits) {
+    public addSplits_args setSplits(java.util.Set<java.nio.ByteBuffer> splits) {
       this.splits = splits;
       return this;
     }
@@ -19012,13 +19650,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -19026,7 +19668,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -19034,14 +19676,14 @@
         if (value == null) {
           unsetSplits();
         } else {
-          setSplits((Set<ByteBuffer>)value);
+          setSplits((java.util.Set<java.nio.ByteBuffer>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -19053,13 +19695,13 @@
         return getSplits();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -19070,11 +19712,11 @@
       case SPLITS:
         return isSetSplits();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof addSplits_args)
@@ -19085,6 +19727,8 @@
     public boolean equals(addSplits_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -19118,24 +19762,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_splits = true && (isSetSplits());
-      list.add(present_splits);
-      if (present_splits)
-        list.add(splits);
+      hashCode = hashCode * 8191 + ((isSetSplits()) ? 131071 : 524287);
+      if (isSetSplits())
+        hashCode = hashCode * 8191 + splits.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -19146,7 +19787,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -19156,7 +19797,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -19166,7 +19807,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetSplits()).compareTo(other.isSetSplits());
+      lastComparison = java.lang.Boolean.valueOf(isSetSplits()).compareTo(other.isSetSplits());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -19184,16 +19825,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("addSplits_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("addSplits_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -19236,7 +19877,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -19244,13 +19885,13 @@
       }
     }
 
-    private static class addSplits_argsStandardSchemeFactory implements SchemeFactory {
+    private static class addSplits_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addSplits_argsStandardScheme getScheme() {
         return new addSplits_argsStandardScheme();
       }
     }
 
-    private static class addSplits_argsStandardScheme extends StandardScheme<addSplits_args> {
+    private static class addSplits_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<addSplits_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, addSplits_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -19282,8 +19923,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set174 = iprot.readSetBegin();
-                  struct.splits = new HashSet<ByteBuffer>(2*_set174.size);
-                  ByteBuffer _elem175;
+                  struct.splits = new java.util.HashSet<java.nio.ByteBuffer>(2*_set174.size);
+                  java.nio.ByteBuffer _elem175;
                   for (int _i176 = 0; _i176 < _set174.size; ++_i176)
                   {
                     _elem175 = iprot.readBinary();
@@ -19325,7 +19966,7 @@
           oprot.writeFieldBegin(SPLITS_FIELD_DESC);
           {
             oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.splits.size()));
-            for (ByteBuffer _iter177 : struct.splits)
+            for (java.nio.ByteBuffer _iter177 : struct.splits)
             {
               oprot.writeBinary(_iter177);
             }
@@ -19339,18 +19980,18 @@
 
     }
 
-    private static class addSplits_argsTupleSchemeFactory implements SchemeFactory {
+    private static class addSplits_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addSplits_argsTupleScheme getScheme() {
         return new addSplits_argsTupleScheme();
       }
     }
 
-    private static class addSplits_argsTupleScheme extends TupleScheme<addSplits_args> {
+    private static class addSplits_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<addSplits_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, addSplits_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -19370,7 +20011,7 @@
         if (struct.isSetSplits()) {
           {
             oprot.writeI32(struct.splits.size());
-            for (ByteBuffer _iter178 : struct.splits)
+            for (java.nio.ByteBuffer _iter178 : struct.splits)
             {
               oprot.writeBinary(_iter178);
             }
@@ -19380,8 +20021,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, addSplits_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -19393,8 +20034,8 @@
         if (incoming.get(2)) {
           {
             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);
-            ByteBuffer _elem180;
+            struct.splits = new java.util.HashSet<java.nio.ByteBuffer>(2*_set179.size);
+            java.nio.ByteBuffer _elem180;
             for (int _i181 = 0; _i181 < _set179.size; ++_i181)
             {
               _elem180 = iprot.readBinary();
@@ -19406,6 +20047,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class addSplits_result implements org.apache.thrift.TBase<addSplits_result, addSplits_result._Fields>, java.io.Serializable, Cloneable, Comparable<addSplits_result>   {
@@ -19415,11 +20059,8 @@
     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 addSplits_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new addSplits_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addSplits_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addSplits_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -19431,10 +20072,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -19461,21 +20102,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -19484,22 +20125,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addSplits_result.class, metaDataMap);
     }
 
@@ -19615,7 +20256,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -19644,7 +20285,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -19656,13 +20297,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -19673,11 +20314,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof addSplits_result)
@@ -19688,6 +20329,8 @@
     public boolean equals(addSplits_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -19721,24 +20364,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -19749,7 +20389,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -19759,7 +20399,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -19769,7 +20409,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -19787,16 +20427,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("addSplits_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("addSplits_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -19839,7 +20479,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -19847,13 +20487,13 @@
       }
     }
 
-    private static class addSplits_resultStandardSchemeFactory implements SchemeFactory {
+    private static class addSplits_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addSplits_resultStandardScheme getScheme() {
         return new addSplits_resultStandardScheme();
       }
     }
 
-    private static class addSplits_resultStandardScheme extends StandardScheme<addSplits_result> {
+    private static class addSplits_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<addSplits_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, addSplits_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -19928,18 +20568,18 @@
 
     }
 
-    private static class addSplits_resultTupleSchemeFactory implements SchemeFactory {
+    private static class addSplits_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addSplits_resultTupleScheme getScheme() {
         return new addSplits_resultTupleScheme();
       }
     }
 
-    private static class addSplits_resultTupleScheme extends TupleScheme<addSplits_result> {
+    private static class addSplits_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<addSplits_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, addSplits_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -19963,8 +20603,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, addSplits_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -19983,6 +20623,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class attachIterator_args implements org.apache.thrift.TBase<attachIterator_args, attachIterator_args._Fields>, java.io.Serializable, Cloneable, Comparable<attachIterator_args>   {
@@ -19993,16 +20636,13 @@
     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 attachIterator_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new attachIterator_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new attachIterator_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new attachIterator_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public IteratorSetting setting; // required
-    public Set<IteratorScope> scopes; // required
+    public java.util.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 {
@@ -20011,10 +20651,10 @@
       SETTING((short)3, "setting"),
       SCOPES((short)4, "scopes");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -20043,21 +20683,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -20066,15 +20706,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -20084,7 +20724,7 @@
       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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(attachIterator_args.class, metaDataMap);
     }
 
@@ -20092,10 +20732,10 @@
     }
 
     public attachIterator_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       IteratorSetting setting,
-      Set<IteratorScope> scopes)
+      java.util.Set<IteratorScope> scopes)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -20118,7 +20758,7 @@
         this.setting = new IteratorSetting(other.setting);
       }
       if (other.isSetScopes()) {
-        Set<IteratorScope> __this__scopes = new HashSet<IteratorScope>(other.scopes.size());
+        java.util.Set<IteratorScope> __this__scopes = new java.util.HashSet<IteratorScope>(other.scopes.size());
         for (IteratorScope other_element : other.scopes) {
           __this__scopes.add(other_element);
         }
@@ -20143,16 +20783,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public attachIterator_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public attachIterator_args setLogin(ByteBuffer login) {
+    public attachIterator_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -20172,11 +20812,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public attachIterator_args setTableName(String tableName) {
+    public attachIterator_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -20230,16 +20870,16 @@
 
     public void addToScopes(IteratorScope elem) {
       if (this.scopes == null) {
-        this.scopes = new HashSet<IteratorScope>();
+        this.scopes = new java.util.HashSet<IteratorScope>();
       }
       this.scopes.add(elem);
     }
 
-    public Set<IteratorScope> getScopes() {
+    public java.util.Set<IteratorScope> getScopes() {
       return this.scopes;
     }
 
-    public attachIterator_args setScopes(Set<IteratorScope> scopes) {
+    public attachIterator_args setScopes(java.util.Set<IteratorScope> scopes) {
       this.scopes = scopes;
       return this;
     }
@@ -20259,13 +20899,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -20273,7 +20917,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -20289,14 +20933,14 @@
         if (value == null) {
           unsetScopes();
         } else {
-          setScopes((Set<IteratorScope>)value);
+          setScopes((java.util.Set<IteratorScope>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -20311,13 +20955,13 @@
         return getScopes();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -20330,11 +20974,11 @@
       case SCOPES:
         return isSetScopes();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof attachIterator_args)
@@ -20345,6 +20989,8 @@
     public boolean equals(attachIterator_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -20387,29 +21033,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_setting = true && (isSetSetting());
-      list.add(present_setting);
-      if (present_setting)
-        list.add(setting);
+      hashCode = hashCode * 8191 + ((isSetSetting()) ? 131071 : 524287);
+      if (isSetSetting())
+        hashCode = hashCode * 8191 + setting.hashCode();
 
-      boolean present_scopes = true && (isSetScopes());
-      list.add(present_scopes);
-      if (present_scopes)
-        list.add(scopes);
+      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
+      if (isSetScopes())
+        hashCode = hashCode * 8191 + scopes.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -20420,7 +21062,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -20430,7 +21072,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -20440,7 +21082,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
+      lastComparison = java.lang.Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -20450,7 +21092,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
+      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -20468,16 +21110,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("attachIterator_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("attachIterator_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -20531,7 +21173,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -20539,13 +21181,13 @@
       }
     }
 
-    private static class attachIterator_argsStandardSchemeFactory implements SchemeFactory {
+    private static class attachIterator_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public attachIterator_argsStandardScheme getScheme() {
         return new attachIterator_argsStandardScheme();
       }
     }
 
-    private static class attachIterator_argsStandardScheme extends StandardScheme<attachIterator_args> {
+    private static class attachIterator_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<attachIterator_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, attachIterator_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -20586,7 +21228,7 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set182 = iprot.readSetBegin();
-                  struct.scopes = new HashSet<IteratorScope>(2*_set182.size);
+                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set182.size);
                   IteratorScope _elem183;
                   for (int _i184 = 0; _i184 < _set182.size; ++_i184)
                   {
@@ -20648,18 +21290,18 @@
 
     }
 
-    private static class attachIterator_argsTupleSchemeFactory implements SchemeFactory {
+    private static class attachIterator_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public attachIterator_argsTupleScheme getScheme() {
         return new attachIterator_argsTupleScheme();
       }
     }
 
-    private static class attachIterator_argsTupleScheme extends TupleScheme<attachIterator_args> {
+    private static class attachIterator_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<attachIterator_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, attachIterator_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -20695,8 +21337,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, attachIterator_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -20713,7 +21355,7 @@
         if (incoming.get(3)) {
           {
             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);
+            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set187.size);
             IteratorScope _elem188;
             for (int _i189 = 0; _i189 < _set187.size; ++_i189)
             {
@@ -20726,6 +21368,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class attachIterator_result implements org.apache.thrift.TBase<attachIterator_result, attachIterator_result._Fields>, java.io.Serializable, Cloneable, Comparable<attachIterator_result>   {
@@ -20735,11 +21380,8 @@
     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 attachIterator_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new attachIterator_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new attachIterator_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new attachIterator_resultTupleSchemeFactory();
 
     public AccumuloSecurityException ouch1; // required
     public AccumuloException ouch2; // required
@@ -20751,10 +21393,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -20781,21 +21423,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -20804,22 +21446,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(attachIterator_result.class, metaDataMap);
     }
 
@@ -20935,7 +21577,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -20964,7 +21606,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -20976,13 +21618,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -20993,11 +21635,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof attachIterator_result)
@@ -21008,6 +21650,8 @@
     public boolean equals(attachIterator_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -21041,24 +21685,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -21069,7 +21710,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -21079,7 +21720,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -21089,7 +21730,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -21107,16 +21748,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("attachIterator_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("attachIterator_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -21159,7 +21800,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -21167,13 +21808,13 @@
       }
     }
 
-    private static class attachIterator_resultStandardSchemeFactory implements SchemeFactory {
+    private static class attachIterator_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public attachIterator_resultStandardScheme getScheme() {
         return new attachIterator_resultStandardScheme();
       }
     }
 
-    private static class attachIterator_resultStandardScheme extends StandardScheme<attachIterator_result> {
+    private static class attachIterator_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<attachIterator_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, attachIterator_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -21248,18 +21889,18 @@
 
     }
 
-    private static class attachIterator_resultTupleSchemeFactory implements SchemeFactory {
+    private static class attachIterator_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public attachIterator_resultTupleScheme getScheme() {
         return new attachIterator_resultTupleScheme();
       }
     }
 
-    private static class attachIterator_resultTupleScheme extends TupleScheme<attachIterator_result> {
+    private static class attachIterator_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<attachIterator_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, attachIterator_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -21283,8 +21924,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, attachIterator_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloSecurityException();
           struct.ouch1.read(iprot);
@@ -21303,6 +21944,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class checkIteratorConflicts_args implements org.apache.thrift.TBase<checkIteratorConflicts_args, checkIteratorConflicts_args._Fields>, java.io.Serializable, Cloneable, Comparable<checkIteratorConflicts_args>   {
@@ -21313,16 +21957,13 @@
     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 checkIteratorConflicts_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new checkIteratorConflicts_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new checkIteratorConflicts_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new checkIteratorConflicts_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public IteratorSetting setting; // required
-    public Set<IteratorScope> scopes; // required
+    public java.util.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 {
@@ -21331,10 +21972,10 @@
       SETTING((short)3, "setting"),
       SCOPES((short)4, "scopes");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -21363,21 +22004,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -21386,15 +22027,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -21404,7 +22045,7 @@
       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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkIteratorConflicts_args.class, metaDataMap);
     }
 
@@ -21412,10 +22053,10 @@
     }
 
     public checkIteratorConflicts_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       IteratorSetting setting,
-      Set<IteratorScope> scopes)
+      java.util.Set<IteratorScope> scopes)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -21438,7 +22079,7 @@
         this.setting = new IteratorSetting(other.setting);
       }
       if (other.isSetScopes()) {
-        Set<IteratorScope> __this__scopes = new HashSet<IteratorScope>(other.scopes.size());
+        java.util.Set<IteratorScope> __this__scopes = new java.util.HashSet<IteratorScope>(other.scopes.size());
         for (IteratorScope other_element : other.scopes) {
           __this__scopes.add(other_element);
         }
@@ -21463,16 +22104,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public checkIteratorConflicts_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public checkIteratorConflicts_args setLogin(ByteBuffer login) {
+    public checkIteratorConflicts_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -21492,11 +22133,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public checkIteratorConflicts_args setTableName(String tableName) {
+    public checkIteratorConflicts_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -21550,16 +22191,16 @@
 
     public void addToScopes(IteratorScope elem) {
       if (this.scopes == null) {
-        this.scopes = new HashSet<IteratorScope>();
+        this.scopes = new java.util.HashSet<IteratorScope>();
       }
       this.scopes.add(elem);
     }
 
-    public Set<IteratorScope> getScopes() {
+    public java.util.Set<IteratorScope> getScopes() {
       return this.scopes;
     }
 
-    public checkIteratorConflicts_args setScopes(Set<IteratorScope> scopes) {
+    public checkIteratorConflicts_args setScopes(java.util.Set<IteratorScope> scopes) {
       this.scopes = scopes;
       return this;
     }
@@ -21579,13 +22220,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -21593,7 +22238,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -21609,14 +22254,14 @@
         if (value == null) {
           unsetScopes();
         } else {
-          setScopes((Set<IteratorScope>)value);
+          setScopes((java.util.Set<IteratorScope>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -21631,13 +22276,13 @@
         return getScopes();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -21650,11 +22295,11 @@
       case SCOPES:
         return isSetScopes();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof checkIteratorConflicts_args)
@@ -21665,6 +22310,8 @@
     public boolean equals(checkIteratorConflicts_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -21707,29 +22354,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_setting = true && (isSetSetting());
-      list.add(present_setting);
-      if (present_setting)
-        list.add(setting);
+      hashCode = hashCode * 8191 + ((isSetSetting()) ? 131071 : 524287);
+      if (isSetSetting())
+        hashCode = hashCode * 8191 + setting.hashCode();
 
-      boolean present_scopes = true && (isSetScopes());
-      list.add(present_scopes);
-      if (present_scopes)
-        list.add(scopes);
+      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
+      if (isSetScopes())
+        hashCode = hashCode * 8191 + scopes.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -21740,7 +22383,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -21750,7 +22393,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -21760,7 +22403,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
+      lastComparison = java.lang.Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -21770,7 +22413,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
+      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -21788,16 +22431,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("checkIteratorConflicts_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("checkIteratorConflicts_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -21851,7 +22494,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -21859,13 +22502,13 @@
       }
     }
 
-    private static class checkIteratorConflicts_argsStandardSchemeFactory implements SchemeFactory {
+    private static class checkIteratorConflicts_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public checkIteratorConflicts_argsStandardScheme getScheme() {
         return new checkIteratorConflicts_argsStandardScheme();
       }
     }
 
-    private static class checkIteratorConflicts_argsStandardScheme extends StandardScheme<checkIteratorConflicts_args> {
+    private static class checkIteratorConflicts_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<checkIteratorConflicts_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, checkIteratorConflicts_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -21906,7 +22549,7 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set190 = iprot.readSetBegin();
-                  struct.scopes = new HashSet<IteratorScope>(2*_set190.size);
+                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set190.size);
                   IteratorScope _elem191;
                   for (int _i192 = 0; _i192 < _set190.size; ++_i192)
                   {
@@ -21968,18 +22611,18 @@
 
     }
 
-    private static class checkIteratorConflicts_argsTupleSchemeFactory implements SchemeFactory {
+    private static class checkIteratorConflicts_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public checkIteratorConflicts_argsTupleScheme getScheme() {
         return new checkIteratorConflicts_argsTupleScheme();
       }
     }
 
-    private static class checkIteratorConflicts_argsTupleScheme extends TupleScheme<checkIteratorConflicts_args> {
+    private static class checkIteratorConflicts_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<checkIteratorConflicts_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, checkIteratorConflicts_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -22015,8 +22658,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, checkIteratorConflicts_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -22033,7 +22676,7 @@
         if (incoming.get(3)) {
           {
             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);
+            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set195.size);
             IteratorScope _elem196;
             for (int _i197 = 0; _i197 < _set195.size; ++_i197)
             {
@@ -22046,6 +22689,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class checkIteratorConflicts_result implements org.apache.thrift.TBase<checkIteratorConflicts_result, checkIteratorConflicts_result._Fields>, java.io.Serializable, Cloneable, Comparable<checkIteratorConflicts_result>   {
@@ -22055,11 +22701,8 @@
     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 checkIteratorConflicts_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new checkIteratorConflicts_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new checkIteratorConflicts_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new checkIteratorConflicts_resultTupleSchemeFactory();
 
     public AccumuloSecurityException ouch1; // required
     public AccumuloException ouch2; // required
@@ -22071,10 +22714,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -22101,21 +22744,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -22124,22 +22767,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkIteratorConflicts_result.class, metaDataMap);
     }
 
@@ -22255,7 +22898,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -22284,7 +22927,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -22296,13 +22939,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -22313,11 +22956,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof checkIteratorConflicts_result)
@@ -22328,6 +22971,8 @@
     public boolean equals(checkIteratorConflicts_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -22361,24 +23006,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -22389,7 +23031,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -22399,7 +23041,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -22409,7 +23051,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -22427,16 +23069,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("checkIteratorConflicts_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("checkIteratorConflicts_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -22479,7 +23121,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -22487,13 +23129,13 @@
       }
     }
 
-    private static class checkIteratorConflicts_resultStandardSchemeFactory implements SchemeFactory {
+    private static class checkIteratorConflicts_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public checkIteratorConflicts_resultStandardScheme getScheme() {
         return new checkIteratorConflicts_resultStandardScheme();
       }
     }
 
-    private static class checkIteratorConflicts_resultStandardScheme extends StandardScheme<checkIteratorConflicts_result> {
+    private static class checkIteratorConflicts_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<checkIteratorConflicts_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, checkIteratorConflicts_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -22568,18 +23210,18 @@
 
     }
 
-    private static class checkIteratorConflicts_resultTupleSchemeFactory implements SchemeFactory {
+    private static class checkIteratorConflicts_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public checkIteratorConflicts_resultTupleScheme getScheme() {
         return new checkIteratorConflicts_resultTupleScheme();
       }
     }
 
-    private static class checkIteratorConflicts_resultTupleScheme extends TupleScheme<checkIteratorConflicts_result> {
+    private static class checkIteratorConflicts_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<checkIteratorConflicts_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, checkIteratorConflicts_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -22603,8 +23245,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, checkIteratorConflicts_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloSecurityException();
           struct.ouch1.read(iprot);
@@ -22623,6 +23265,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class clearLocatorCache_args implements org.apache.thrift.TBase<clearLocatorCache_args, clearLocatorCache_args._Fields>, java.io.Serializable, Cloneable, Comparable<clearLocatorCache_args>   {
@@ -22631,24 +23276,21 @@
     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 TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", 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 clearLocatorCache_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new clearLocatorCache_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new clearLocatorCache_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new clearLocatorCache_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // 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"),
       TABLE_NAME((short)2, "tableName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -22673,21 +23315,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -22696,20 +23338,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(clearLocatorCache_args.class, metaDataMap);
     }
 
@@ -22717,8 +23359,8 @@
     }
 
     public clearLocatorCache_args(
-      ByteBuffer login,
-      String tableName)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -22752,16 +23394,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public clearLocatorCache_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public clearLocatorCache_args setLogin(ByteBuffer login) {
+    public clearLocatorCache_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -22781,11 +23423,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public clearLocatorCache_args setTableName(String tableName) {
+    public clearLocatorCache_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -22805,13 +23447,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -22819,14 +23465,14 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -22835,13 +23481,13 @@
         return getTableName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -22850,11 +23496,11 @@
       case TABLE_NAME:
         return isSetTableName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof clearLocatorCache_args)
@@ -22865,6 +23511,8 @@
     public boolean equals(clearLocatorCache_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -22889,19 +23537,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -22912,7 +23558,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -22922,7 +23568,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -22940,16 +23586,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("clearLocatorCache_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("clearLocatorCache_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -22984,7 +23630,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -22992,13 +23638,13 @@
       }
     }
 
-    private static class clearLocatorCache_argsStandardSchemeFactory implements SchemeFactory {
+    private static class clearLocatorCache_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public clearLocatorCache_argsStandardScheme getScheme() {
         return new clearLocatorCache_argsStandardScheme();
       }
     }
 
-    private static class clearLocatorCache_argsStandardScheme extends StandardScheme<clearLocatorCache_args> {
+    private static class clearLocatorCache_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<clearLocatorCache_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, clearLocatorCache_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -23057,18 +23703,18 @@
 
     }
 
-    private static class clearLocatorCache_argsTupleSchemeFactory implements SchemeFactory {
+    private static class clearLocatorCache_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public clearLocatorCache_argsTupleScheme getScheme() {
         return new clearLocatorCache_argsTupleScheme();
       }
     }
 
-    private static class clearLocatorCache_argsTupleScheme extends TupleScheme<clearLocatorCache_args> {
+    private static class clearLocatorCache_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<clearLocatorCache_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, clearLocatorCache_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -23086,8 +23732,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, clearLocatorCache_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -23099,6 +23745,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class clearLocatorCache_result implements org.apache.thrift.TBase<clearLocatorCache_result, clearLocatorCache_result._Fields>, java.io.Serializable, Cloneable, Comparable<clearLocatorCache_result>   {
@@ -23106,11 +23755,8 @@
 
     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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new clearLocatorCache_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new clearLocatorCache_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new clearLocatorCache_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new clearLocatorCache_resultTupleSchemeFactory();
 
     public TableNotFoundException ouch1; // required
 
@@ -23118,10 +23764,10 @@
     public enum _Fields implements org.apache.thrift.TFieldIdEnum {
       OUCH1((short)1, "ouch1");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -23144,21 +23790,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -23167,18 +23813,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(clearLocatorCache_result.class, metaDataMap);
     }
 
@@ -23234,7 +23880,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -23247,30 +23893,30 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case OUCH1:
         return isSetOuch1();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof clearLocatorCache_result)
@@ -23281,6 +23927,8 @@
     public boolean equals(clearLocatorCache_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -23296,14 +23944,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -23314,7 +23961,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -23332,16 +23979,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("clearLocatorCache_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("clearLocatorCache_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -23368,7 +24015,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -23376,13 +24023,13 @@
       }
     }
 
-    private static class clearLocatorCache_resultStandardSchemeFactory implements SchemeFactory {
+    private static class clearLocatorCache_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public clearLocatorCache_resultStandardScheme getScheme() {
         return new clearLocatorCache_resultStandardScheme();
       }
     }
 
-    private static class clearLocatorCache_resultStandardScheme extends StandardScheme<clearLocatorCache_result> {
+    private static class clearLocatorCache_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<clearLocatorCache_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, clearLocatorCache_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -23429,18 +24076,18 @@
 
     }
 
-    private static class clearLocatorCache_resultTupleSchemeFactory implements SchemeFactory {
+    private static class clearLocatorCache_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public clearLocatorCache_resultTupleScheme getScheme() {
         return new clearLocatorCache_resultTupleScheme();
       }
     }
 
-    private static class clearLocatorCache_resultTupleScheme extends TupleScheme<clearLocatorCache_result> {
+    private static class clearLocatorCache_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<clearLocatorCache_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, clearLocatorCache_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -23452,8 +24099,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, clearLocatorCache_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.ouch1 = new TableNotFoundException();
           struct.ouch1.read(iprot);
@@ -23462,6 +24109,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class cloneTable_args implements org.apache.thrift.TBase<cloneTable_args, cloneTable_args._Fields>, java.io.Serializable, Cloneable, Comparable<cloneTable_args>   {
@@ -23474,18 +24124,15 @@
     private static final org.apache.thrift.protocol.TField PROPERTIES_TO_SET_FIELD_DESC = new org.apache.thrift.protocol.TField("propertiesToSet", org.apache.thrift.protocol.TType.MAP, (short)5);
     private static final org.apache.thrift.protocol.TField PROPERTIES_TO_EXCLUDE_FIELD_DESC = new org.apache.thrift.protocol.TField("propertiesToExclude", org.apache.thrift.protocol.TType.SET, (short)6);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new cloneTable_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new cloneTable_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new cloneTable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new cloneTable_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public String newTableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.lang.String newTableName; // required
     public boolean flush; // required
-    public Map<String,String> propertiesToSet; // required
-    public Set<String> propertiesToExclude; // required
+    public java.util.Map<java.lang.String,java.lang.String> propertiesToSet; // required
+    public java.util.Set<java.lang.String> propertiesToExclude; // 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 {
@@ -23496,10 +24143,10 @@
       PROPERTIES_TO_SET((short)5, "propertiesToSet"),
       PROPERTIES_TO_EXCLUDE((short)6, "propertiesToExclude");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -23532,21 +24179,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -23555,7 +24202,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -23563,9 +24210,9 @@
     // isset id assignments
     private static final int __FLUSH_ISSET_ID = 0;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -23581,7 +24228,7 @@
       tmpMap.put(_Fields.PROPERTIES_TO_EXCLUDE, new org.apache.thrift.meta_data.FieldMetaData("propertiesToExclude", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
               new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(cloneTable_args.class, metaDataMap);
     }
 
@@ -23589,12 +24236,12 @@
     }
 
     public cloneTable_args(
-      ByteBuffer login,
-      String tableName,
-      String newTableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.lang.String newTableName,
       boolean flush,
-      Map<String,String> propertiesToSet,
-      Set<String> propertiesToExclude)
+      java.util.Map<java.lang.String,java.lang.String> propertiesToSet,
+      java.util.Set<java.lang.String> propertiesToExclude)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -23622,11 +24269,11 @@
       }
       this.flush = other.flush;
       if (other.isSetPropertiesToSet()) {
-        Map<String,String> __this__propertiesToSet = new HashMap<String,String>(other.propertiesToSet);
+        java.util.Map<java.lang.String,java.lang.String> __this__propertiesToSet = new java.util.HashMap<java.lang.String,java.lang.String>(other.propertiesToSet);
         this.propertiesToSet = __this__propertiesToSet;
       }
       if (other.isSetPropertiesToExclude()) {
-        Set<String> __this__propertiesToExclude = new HashSet<String>(other.propertiesToExclude);
+        java.util.Set<java.lang.String> __this__propertiesToExclude = new java.util.HashSet<java.lang.String>(other.propertiesToExclude);
         this.propertiesToExclude = __this__propertiesToExclude;
       }
     }
@@ -23651,16 +24298,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public cloneTable_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public cloneTable_args setLogin(ByteBuffer login) {
+    public cloneTable_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -23680,11 +24327,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public cloneTable_args setTableName(String tableName) {
+    public cloneTable_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -23704,11 +24351,11 @@
       }
     }
 
-    public String getNewTableName() {
+    public java.lang.String getNewTableName() {
       return this.newTableName;
     }
 
-    public cloneTable_args setNewTableName(String newTableName) {
+    public cloneTable_args setNewTableName(java.lang.String newTableName) {
       this.newTableName = newTableName;
       return this;
     }
@@ -23739,34 +24386,34 @@
     }
 
     public void unsetFlush() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __FLUSH_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __FLUSH_ISSET_ID);
     }
 
     /** Returns true if field flush is set (has been assigned a value) and false otherwise */
     public boolean isSetFlush() {
-      return EncodingUtils.testBit(__isset_bitfield, __FLUSH_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __FLUSH_ISSET_ID);
     }
 
     public void setFlushIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __FLUSH_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __FLUSH_ISSET_ID, value);
     }
 
     public int getPropertiesToSetSize() {
       return (this.propertiesToSet == null) ? 0 : this.propertiesToSet.size();
     }
 
-    public void putToPropertiesToSet(String key, String val) {
+    public void putToPropertiesToSet(java.lang.String key, java.lang.String val) {
       if (this.propertiesToSet == null) {
-        this.propertiesToSet = new HashMap<String,String>();
+        this.propertiesToSet = new java.util.HashMap<java.lang.String,java.lang.String>();
       }
       this.propertiesToSet.put(key, val);
     }
 
-    public Map<String,String> getPropertiesToSet() {
+    public java.util.Map<java.lang.String,java.lang.String> getPropertiesToSet() {
       return this.propertiesToSet;
     }
 
-    public cloneTable_args setPropertiesToSet(Map<String,String> propertiesToSet) {
+    public cloneTable_args setPropertiesToSet(java.util.Map<java.lang.String,java.lang.String> propertiesToSet) {
       this.propertiesToSet = propertiesToSet;
       return this;
     }
@@ -23790,22 +24437,22 @@
       return (this.propertiesToExclude == null) ? 0 : this.propertiesToExclude.size();
     }
 
-    public java.util.Iterator<String> getPropertiesToExcludeIterator() {
+    public java.util.Iterator<java.lang.String> getPropertiesToExcludeIterator() {
       return (this.propertiesToExclude == null) ? null : this.propertiesToExclude.iterator();
     }
 
-    public void addToPropertiesToExclude(String elem) {
+    public void addToPropertiesToExclude(java.lang.String elem) {
       if (this.propertiesToExclude == null) {
-        this.propertiesToExclude = new HashSet<String>();
+        this.propertiesToExclude = new java.util.HashSet<java.lang.String>();
       }
       this.propertiesToExclude.add(elem);
     }
 
-    public Set<String> getPropertiesToExclude() {
+    public java.util.Set<java.lang.String> getPropertiesToExclude() {
       return this.propertiesToExclude;
     }
 
-    public cloneTable_args setPropertiesToExclude(Set<String> propertiesToExclude) {
+    public cloneTable_args setPropertiesToExclude(java.util.Set<java.lang.String> propertiesToExclude) {
       this.propertiesToExclude = propertiesToExclude;
       return this;
     }
@@ -23825,13 +24472,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -23839,7 +24490,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -23847,7 +24498,7 @@
         if (value == null) {
           unsetNewTableName();
         } else {
-          setNewTableName((String)value);
+          setNewTableName((java.lang.String)value);
         }
         break;
 
@@ -23855,7 +24506,7 @@
         if (value == null) {
           unsetFlush();
         } else {
-          setFlush((Boolean)value);
+          setFlush((java.lang.Boolean)value);
         }
         break;
 
@@ -23863,7 +24514,7 @@
         if (value == null) {
           unsetPropertiesToSet();
         } else {
-          setPropertiesToSet((Map<String,String>)value);
+          setPropertiesToSet((java.util.Map<java.lang.String,java.lang.String>)value);
         }
         break;
 
@@ -23871,14 +24522,14 @@
         if (value == null) {
           unsetPropertiesToExclude();
         } else {
-          setPropertiesToExclude((Set<String>)value);
+          setPropertiesToExclude((java.util.Set<java.lang.String>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -23899,13 +24550,13 @@
         return getPropertiesToExclude();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -23922,11 +24573,11 @@
       case PROPERTIES_TO_EXCLUDE:
         return isSetPropertiesToExclude();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof cloneTable_args)
@@ -23937,6 +24588,8 @@
     public boolean equals(cloneTable_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -23997,39 +24650,31 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_newTableName = true && (isSetNewTableName());
-      list.add(present_newTableName);
-      if (present_newTableName)
-        list.add(newTableName);
+      hashCode = hashCode * 8191 + ((isSetNewTableName()) ? 131071 : 524287);
+      if (isSetNewTableName())
+        hashCode = hashCode * 8191 + newTableName.hashCode();
 
-      boolean present_flush = true;
-      list.add(present_flush);
-      if (present_flush)
-        list.add(flush);
+      hashCode = hashCode * 8191 + ((flush) ? 131071 : 524287);
 
-      boolean present_propertiesToSet = true && (isSetPropertiesToSet());
-      list.add(present_propertiesToSet);
-      if (present_propertiesToSet)
-        list.add(propertiesToSet);
+      hashCode = hashCode * 8191 + ((isSetPropertiesToSet()) ? 131071 : 524287);
+      if (isSetPropertiesToSet())
+        hashCode = hashCode * 8191 + propertiesToSet.hashCode();
 
-      boolean present_propertiesToExclude = true && (isSetPropertiesToExclude());
-      list.add(present_propertiesToExclude);
-      if (present_propertiesToExclude)
-        list.add(propertiesToExclude);
+      hashCode = hashCode * 8191 + ((isSetPropertiesToExclude()) ? 131071 : 524287);
+      if (isSetPropertiesToExclude())
+        hashCode = hashCode * 8191 + propertiesToExclude.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -24040,7 +24685,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -24050,7 +24695,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -24060,7 +24705,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNewTableName()).compareTo(other.isSetNewTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNewTableName()).compareTo(other.isSetNewTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -24070,7 +24715,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetFlush()).compareTo(other.isSetFlush());
+      lastComparison = java.lang.Boolean.valueOf(isSetFlush()).compareTo(other.isSetFlush());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -24080,7 +24725,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPropertiesToSet()).compareTo(other.isSetPropertiesToSet());
+      lastComparison = java.lang.Boolean.valueOf(isSetPropertiesToSet()).compareTo(other.isSetPropertiesToSet());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -24090,7 +24735,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPropertiesToExclude()).compareTo(other.isSetPropertiesToExclude());
+      lastComparison = java.lang.Boolean.valueOf(isSetPropertiesToExclude()).compareTo(other.isSetPropertiesToExclude());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -24108,16 +24753,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("cloneTable_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("cloneTable_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -24180,7 +24825,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -24190,13 +24835,13 @@
       }
     }
 
-    private static class cloneTable_argsStandardSchemeFactory implements SchemeFactory {
+    private static class cloneTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public cloneTable_argsStandardScheme getScheme() {
         return new cloneTable_argsStandardScheme();
       }
     }
 
-    private static class cloneTable_argsStandardScheme extends StandardScheme<cloneTable_args> {
+    private static class cloneTable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<cloneTable_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, cloneTable_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -24244,9 +24889,9 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map198 = iprot.readMapBegin();
-                  struct.propertiesToSet = new HashMap<String,String>(2*_map198.size);
-                  String _key199;
-                  String _val200;
+                  struct.propertiesToSet = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map198.size);
+                  java.lang.String _key199;
+                  java.lang.String _val200;
                   for (int _i201 = 0; _i201 < _map198.size; ++_i201)
                   {
                     _key199 = iprot.readString();
@@ -24264,8 +24909,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set202 = iprot.readSetBegin();
-                  struct.propertiesToExclude = new HashSet<String>(2*_set202.size);
-                  String _elem203;
+                  struct.propertiesToExclude = new java.util.HashSet<java.lang.String>(2*_set202.size);
+                  java.lang.String _elem203;
                   for (int _i204 = 0; _i204 < _set202.size; ++_i204)
                   {
                     _elem203 = iprot.readString();
@@ -24315,7 +24960,7 @@
           oprot.writeFieldBegin(PROPERTIES_TO_SET_FIELD_DESC);
           {
             oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.propertiesToSet.size()));
-            for (Map.Entry<String, String> _iter205 : struct.propertiesToSet.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter205 : struct.propertiesToSet.entrySet())
             {
               oprot.writeString(_iter205.getKey());
               oprot.writeString(_iter205.getValue());
@@ -24328,7 +24973,7 @@
           oprot.writeFieldBegin(PROPERTIES_TO_EXCLUDE_FIELD_DESC);
           {
             oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.propertiesToExclude.size()));
-            for (String _iter206 : struct.propertiesToExclude)
+            for (java.lang.String _iter206 : struct.propertiesToExclude)
             {
               oprot.writeString(_iter206);
             }
@@ -24342,18 +24987,18 @@
 
     }
 
-    private static class cloneTable_argsTupleSchemeFactory implements SchemeFactory {
+    private static class cloneTable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public cloneTable_argsTupleScheme getScheme() {
         return new cloneTable_argsTupleScheme();
       }
     }
 
-    private static class cloneTable_argsTupleScheme extends TupleScheme<cloneTable_args> {
+    private static class cloneTable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<cloneTable_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, cloneTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -24388,7 +25033,7 @@
         if (struct.isSetPropertiesToSet()) {
           {
             oprot.writeI32(struct.propertiesToSet.size());
-            for (Map.Entry<String, String> _iter207 : struct.propertiesToSet.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter207 : struct.propertiesToSet.entrySet())
             {
               oprot.writeString(_iter207.getKey());
               oprot.writeString(_iter207.getValue());
@@ -24398,7 +25043,7 @@
         if (struct.isSetPropertiesToExclude()) {
           {
             oprot.writeI32(struct.propertiesToExclude.size());
-            for (String _iter208 : struct.propertiesToExclude)
+            for (java.lang.String _iter208 : struct.propertiesToExclude)
             {
               oprot.writeString(_iter208);
             }
@@ -24408,8 +25053,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, cloneTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(6);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(6);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -24429,9 +25074,9 @@
         if (incoming.get(4)) {
           {
             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);
-            String _key210;
-            String _val211;
+            struct.propertiesToSet = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map209.size);
+            java.lang.String _key210;
+            java.lang.String _val211;
             for (int _i212 = 0; _i212 < _map209.size; ++_i212)
             {
               _key210 = iprot.readString();
@@ -24444,8 +25089,8 @@
         if (incoming.get(5)) {
           {
             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);
-            String _elem214;
+            struct.propertiesToExclude = new java.util.HashSet<java.lang.String>(2*_set213.size);
+            java.lang.String _elem214;
             for (int _i215 = 0; _i215 < _set213.size; ++_i215)
             {
               _elem214 = iprot.readString();
@@ -24457,6 +25102,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class cloneTable_result implements org.apache.thrift.TBase<cloneTable_result, cloneTable_result._Fields>, java.io.Serializable, Cloneable, Comparable<cloneTable_result>   {
@@ -24467,11 +25115,8 @@
     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 cloneTable_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new cloneTable_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new cloneTable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new cloneTable_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -24485,10 +25130,10 @@
       OUCH3((short)3, "ouch3"),
       OUCH4((short)4, "ouch4");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -24517,21 +25162,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -24540,24 +25185,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableExistsException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(cloneTable_result.class, metaDataMap);
     }
 
@@ -24703,7 +25348,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -24740,7 +25385,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -24755,13 +25400,13 @@
         return getOuch4();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -24774,11 +25419,11 @@
       case OUCH4:
         return isSetOuch4();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof cloneTable_result)
@@ -24789,6 +25434,8 @@
     public boolean equals(cloneTable_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -24831,29 +25478,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      boolean present_ouch4 = true && (isSetOuch4());
-      list.add(present_ouch4);
-      if (present_ouch4)
-        list.add(ouch4);
+      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
+      if (isSetOuch4())
+        hashCode = hashCode * 8191 + ouch4.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -24864,7 +25507,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -24874,7 +25517,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -24884,7 +25527,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -24894,7 +25537,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -24912,16 +25555,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("cloneTable_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("cloneTable_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -24972,7 +25615,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -24980,13 +25623,13 @@
       }
     }
 
-    private static class cloneTable_resultStandardSchemeFactory implements SchemeFactory {
+    private static class cloneTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public cloneTable_resultStandardScheme getScheme() {
         return new cloneTable_resultStandardScheme();
       }
     }
 
-    private static class cloneTable_resultStandardScheme extends StandardScheme<cloneTable_result> {
+    private static class cloneTable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<cloneTable_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, cloneTable_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -25075,18 +25718,18 @@
 
     }
 
-    private static class cloneTable_resultTupleSchemeFactory implements SchemeFactory {
+    private static class cloneTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public cloneTable_resultTupleScheme getScheme() {
         return new cloneTable_resultTupleScheme();
       }
     }
 
-    private static class cloneTable_resultTupleScheme extends TupleScheme<cloneTable_result> {
+    private static class cloneTable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<cloneTable_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, cloneTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -25116,8 +25759,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, cloneTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -25141,6 +25784,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class compactTable_args implements org.apache.thrift.TBase<compactTable_args, compactTable_args._Fields>, java.io.Serializable, Cloneable, Comparable<compactTable_args>   {
@@ -25155,17 +25801,14 @@
     private static final org.apache.thrift.protocol.TField WAIT_FIELD_DESC = new org.apache.thrift.protocol.TField("wait", org.apache.thrift.protocol.TType.BOOL, (short)7);
     private static final org.apache.thrift.protocol.TField COMPACTION_STRATEGY_FIELD_DESC = new org.apache.thrift.protocol.TField("compactionStrategy", org.apache.thrift.protocol.TType.STRUCT, (short)8);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new compactTable_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new compactTable_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new compactTable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new compactTable_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public ByteBuffer startRow; // required
-    public ByteBuffer endRow; // required
-    public List<IteratorSetting> iterators; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.nio.ByteBuffer startRow; // required
+    public java.nio.ByteBuffer endRow; // required
+    public java.util.List<IteratorSetting> iterators; // required
     public boolean flush; // required
     public boolean wait; // required
     public CompactionStrategyConfig compactionStrategy; // required
@@ -25181,10 +25824,10 @@
       WAIT((short)7, "wait"),
       COMPACTION_STRATEGY((short)8, "compactionStrategy");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -25221,21 +25864,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -25244,7 +25887,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -25253,9 +25896,9 @@
     private static final int __FLUSH_ISSET_ID = 0;
     private static final int __WAIT_ISSET_ID = 1;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -25273,7 +25916,7 @@
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
       tmpMap.put(_Fields.COMPACTION_STRATEGY, new org.apache.thrift.meta_data.FieldMetaData("compactionStrategy", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, CompactionStrategyConfig.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(compactTable_args.class, metaDataMap);
     }
 
@@ -25281,11 +25924,11 @@
     }
 
     public compactTable_args(
-      ByteBuffer login,
-      String tableName,
-      ByteBuffer startRow,
-      ByteBuffer endRow,
-      List<IteratorSetting> iterators,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.nio.ByteBuffer startRow,
+      java.nio.ByteBuffer endRow,
+      java.util.List<IteratorSetting> iterators,
       boolean flush,
       boolean wait,
       CompactionStrategyConfig compactionStrategy)
@@ -25321,7 +25964,7 @@
         this.endRow = org.apache.thrift.TBaseHelper.copyBinary(other.endRow);
       }
       if (other.isSetIterators()) {
-        List<IteratorSetting> __this__iterators = new ArrayList<IteratorSetting>(other.iterators.size());
+        java.util.List<IteratorSetting> __this__iterators = new java.util.ArrayList<IteratorSetting>(other.iterators.size());
         for (IteratorSetting other_element : other.iterators) {
           __this__iterators.add(new IteratorSetting(other_element));
         }
@@ -25357,16 +26000,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public compactTable_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public compactTable_args setLogin(ByteBuffer login) {
+    public compactTable_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -25386,11 +26029,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public compactTable_args setTableName(String tableName) {
+    public compactTable_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -25415,16 +26058,16 @@
       return startRow == null ? null : startRow.array();
     }
 
-    public ByteBuffer bufferForStartRow() {
+    public java.nio.ByteBuffer bufferForStartRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(startRow);
     }
 
     public compactTable_args setStartRow(byte[] startRow) {
-      this.startRow = startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(startRow, startRow.length));
+      this.startRow = startRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(startRow.clone());
       return this;
     }
 
-    public compactTable_args setStartRow(ByteBuffer startRow) {
+    public compactTable_args setStartRow(java.nio.ByteBuffer startRow) {
       this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       return this;
     }
@@ -25449,16 +26092,16 @@
       return endRow == null ? null : endRow.array();
     }
 
-    public ByteBuffer bufferForEndRow() {
+    public java.nio.ByteBuffer bufferForEndRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     public compactTable_args setEndRow(byte[] endRow) {
-      this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
+      this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
       return this;
     }
 
-    public compactTable_args setEndRow(ByteBuffer endRow) {
+    public compactTable_args setEndRow(java.nio.ByteBuffer endRow) {
       this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       return this;
     }
@@ -25488,16 +26131,16 @@
 
     public void addToIterators(IteratorSetting elem) {
       if (this.iterators == null) {
-        this.iterators = new ArrayList<IteratorSetting>();
+        this.iterators = new java.util.ArrayList<IteratorSetting>();
       }
       this.iterators.add(elem);
     }
 
-    public List<IteratorSetting> getIterators() {
+    public java.util.List<IteratorSetting> getIterators() {
       return this.iterators;
     }
 
-    public compactTable_args setIterators(List<IteratorSetting> iterators) {
+    public compactTable_args setIterators(java.util.List<IteratorSetting> iterators) {
       this.iterators = iterators;
       return this;
     }
@@ -25528,16 +26171,16 @@
     }
 
     public void unsetFlush() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __FLUSH_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __FLUSH_ISSET_ID);
     }
 
     /** Returns true if field flush is set (has been assigned a value) and false otherwise */
     public boolean isSetFlush() {
-      return EncodingUtils.testBit(__isset_bitfield, __FLUSH_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __FLUSH_ISSET_ID);
     }
 
     public void setFlushIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __FLUSH_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __FLUSH_ISSET_ID, value);
     }
 
     public boolean isWait() {
@@ -25551,16 +26194,16 @@
     }
 
     public void unsetWait() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __WAIT_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __WAIT_ISSET_ID);
     }
 
     /** Returns true if field wait is set (has been assigned a value) and false otherwise */
     public boolean isSetWait() {
-      return EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
     }
 
     public void setWaitIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
     }
 
     public CompactionStrategyConfig getCompactionStrategy() {
@@ -25587,13 +26230,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -25601,7 +26248,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -25609,7 +26256,11 @@
         if (value == null) {
           unsetStartRow();
         } else {
-          setStartRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setStartRow((byte[])value);
+          } else {
+            setStartRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -25617,7 +26268,11 @@
         if (value == null) {
           unsetEndRow();
         } else {
-          setEndRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setEndRow((byte[])value);
+          } else {
+            setEndRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -25625,7 +26280,7 @@
         if (value == null) {
           unsetIterators();
         } else {
-          setIterators((List<IteratorSetting>)value);
+          setIterators((java.util.List<IteratorSetting>)value);
         }
         break;
 
@@ -25633,7 +26288,7 @@
         if (value == null) {
           unsetFlush();
         } else {
-          setFlush((Boolean)value);
+          setFlush((java.lang.Boolean)value);
         }
         break;
 
@@ -25641,7 +26296,7 @@
         if (value == null) {
           unsetWait();
         } else {
-          setWait((Boolean)value);
+          setWait((java.lang.Boolean)value);
         }
         break;
 
@@ -25656,7 +26311,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -25683,13 +26338,13 @@
         return getCompactionStrategy();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -25710,11 +26365,11 @@
       case COMPACTION_STRATEGY:
         return isSetCompactionStrategy();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof compactTable_args)
@@ -25725,6 +26380,8 @@
     public boolean equals(compactTable_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -25803,49 +26460,37 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_startRow = true && (isSetStartRow());
-      list.add(present_startRow);
-      if (present_startRow)
-        list.add(startRow);
+      hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
+      if (isSetStartRow())
+        hashCode = hashCode * 8191 + startRow.hashCode();
 
-      boolean present_endRow = true && (isSetEndRow());
-      list.add(present_endRow);
-      if (present_endRow)
-        list.add(endRow);
+      hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
+      if (isSetEndRow())
+        hashCode = hashCode * 8191 + endRow.hashCode();
 
-      boolean present_iterators = true && (isSetIterators());
-      list.add(present_iterators);
-      if (present_iterators)
-        list.add(iterators);
+      hashCode = hashCode * 8191 + ((isSetIterators()) ? 131071 : 524287);
+      if (isSetIterators())
+        hashCode = hashCode * 8191 + iterators.hashCode();
 
-      boolean present_flush = true;
-      list.add(present_flush);
-      if (present_flush)
-        list.add(flush);
+      hashCode = hashCode * 8191 + ((flush) ? 131071 : 524287);
 
-      boolean present_wait = true;
-      list.add(present_wait);
-      if (present_wait)
-        list.add(wait);
+      hashCode = hashCode * 8191 + ((wait) ? 131071 : 524287);
 
-      boolean present_compactionStrategy = true && (isSetCompactionStrategy());
-      list.add(present_compactionStrategy);
-      if (present_compactionStrategy)
-        list.add(compactionStrategy);
+      hashCode = hashCode * 8191 + ((isSetCompactionStrategy()) ? 131071 : 524287);
+      if (isSetCompactionStrategy())
+        hashCode = hashCode * 8191 + compactionStrategy.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -25856,7 +26501,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -25866,7 +26511,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -25876,7 +26521,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -25886,7 +26531,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -25896,7 +26541,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
+      lastComparison = java.lang.Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -25906,7 +26551,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetFlush()).compareTo(other.isSetFlush());
+      lastComparison = java.lang.Boolean.valueOf(isSetFlush()).compareTo(other.isSetFlush());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -25916,7 +26561,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
+      lastComparison = java.lang.Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -25926,7 +26571,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetCompactionStrategy()).compareTo(other.isSetCompactionStrategy());
+      lastComparison = java.lang.Boolean.valueOf(isSetCompactionStrategy()).compareTo(other.isSetCompactionStrategy());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -25944,16 +26589,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("compactTable_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("compactTable_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -26031,7 +26676,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -26041,13 +26686,13 @@
       }
     }
 
-    private static class compactTable_argsStandardSchemeFactory implements SchemeFactory {
+    private static class compactTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public compactTable_argsStandardScheme getScheme() {
         return new compactTable_argsStandardScheme();
       }
     }
 
-    private static class compactTable_argsStandardScheme extends StandardScheme<compactTable_args> {
+    private static class compactTable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<compactTable_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, compactTable_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -26095,7 +26740,7 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                 {
                   org.apache.thrift.protocol.TList _list216 = iprot.readListBegin();
-                  struct.iterators = new ArrayList<IteratorSetting>(_list216.size);
+                  struct.iterators = new java.util.ArrayList<IteratorSetting>(_list216.size);
                   IteratorSetting _elem217;
                   for (int _i218 = 0; _i218 < _list216.size; ++_i218)
                   {
@@ -26199,18 +26844,18 @@
 
     }
 
-    private static class compactTable_argsTupleSchemeFactory implements SchemeFactory {
+    private static class compactTable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public compactTable_argsTupleScheme getScheme() {
         return new compactTable_argsTupleScheme();
       }
     }
 
-    private static class compactTable_argsTupleScheme extends TupleScheme<compactTable_args> {
+    private static class compactTable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<compactTable_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, compactTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -26270,8 +26915,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, compactTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(8);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(8);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -26291,7 +26936,7 @@
         if (incoming.get(4)) {
           {
             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);
+            struct.iterators = new java.util.ArrayList<IteratorSetting>(_list221.size);
             IteratorSetting _elem222;
             for (int _i223 = 0; _i223 < _list221.size; ++_i223)
             {
@@ -26318,6 +26963,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class compactTable_result implements org.apache.thrift.TBase<compactTable_result, compactTable_result._Fields>, java.io.Serializable, Cloneable, Comparable<compactTable_result>   {
@@ -26327,11 +26975,8 @@
     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 compactTable_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new compactTable_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new compactTable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new compactTable_resultTupleSchemeFactory();
 
     public AccumuloSecurityException ouch1; // required
     public TableNotFoundException ouch2; // required
@@ -26343,10 +26988,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -26373,21 +27018,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -26396,22 +27041,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(compactTable_result.class, metaDataMap);
     }
 
@@ -26527,7 +27172,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -26556,7 +27201,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -26568,13 +27213,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -26585,11 +27230,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof compactTable_result)
@@ -26600,6 +27245,8 @@
     public boolean equals(compactTable_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -26633,24 +27280,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -26661,7 +27305,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -26671,7 +27315,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -26681,7 +27325,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -26699,16 +27343,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("compactTable_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("compactTable_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -26751,7 +27395,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -26759,13 +27403,13 @@
       }
     }
 
-    private static class compactTable_resultStandardSchemeFactory implements SchemeFactory {
+    private static class compactTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public compactTable_resultStandardScheme getScheme() {
         return new compactTable_resultStandardScheme();
       }
     }
 
-    private static class compactTable_resultStandardScheme extends StandardScheme<compactTable_result> {
+    private static class compactTable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<compactTable_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, compactTable_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -26840,18 +27484,18 @@
 
     }
 
-    private static class compactTable_resultTupleSchemeFactory implements SchemeFactory {
+    private static class compactTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public compactTable_resultTupleScheme getScheme() {
         return new compactTable_resultTupleScheme();
       }
     }
 
-    private static class compactTable_resultTupleScheme extends TupleScheme<compactTable_result> {
+    private static class compactTable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<compactTable_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, compactTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -26875,8 +27519,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, compactTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloSecurityException();
           struct.ouch1.read(iprot);
@@ -26895,6 +27539,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class cancelCompaction_args implements org.apache.thrift.TBase<cancelCompaction_args, cancelCompaction_args._Fields>, java.io.Serializable, Cloneable, Comparable<cancelCompaction_args>   {
@@ -26903,24 +27550,21 @@
     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 TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", 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 cancelCompaction_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new cancelCompaction_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new cancelCompaction_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new cancelCompaction_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // 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"),
       TABLE_NAME((short)2, "tableName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -26945,21 +27589,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -26968,20 +27612,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(cancelCompaction_args.class, metaDataMap);
     }
 
@@ -26989,8 +27633,8 @@
     }
 
     public cancelCompaction_args(
-      ByteBuffer login,
-      String tableName)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -27024,16 +27668,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public cancelCompaction_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public cancelCompaction_args setLogin(ByteBuffer login) {
+    public cancelCompaction_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -27053,11 +27697,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public cancelCompaction_args setTableName(String tableName) {
+    public cancelCompaction_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -27077,13 +27721,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -27091,14 +27739,14 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -27107,13 +27755,13 @@
         return getTableName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -27122,11 +27770,11 @@
       case TABLE_NAME:
         return isSetTableName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof cancelCompaction_args)
@@ -27137,6 +27785,8 @@
     public boolean equals(cancelCompaction_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -27161,19 +27811,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -27184,7 +27832,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -27194,7 +27842,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -27212,16 +27860,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("cancelCompaction_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("cancelCompaction_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -27256,7 +27904,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -27264,13 +27912,13 @@
       }
     }
 
-    private static class cancelCompaction_argsStandardSchemeFactory implements SchemeFactory {
+    private static class cancelCompaction_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public cancelCompaction_argsStandardScheme getScheme() {
         return new cancelCompaction_argsStandardScheme();
       }
     }
 
-    private static class cancelCompaction_argsStandardScheme extends StandardScheme<cancelCompaction_args> {
+    private static class cancelCompaction_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<cancelCompaction_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, cancelCompaction_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -27329,18 +27977,18 @@
 
     }
 
-    private static class cancelCompaction_argsTupleSchemeFactory implements SchemeFactory {
+    private static class cancelCompaction_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public cancelCompaction_argsTupleScheme getScheme() {
         return new cancelCompaction_argsTupleScheme();
       }
     }
 
-    private static class cancelCompaction_argsTupleScheme extends TupleScheme<cancelCompaction_args> {
+    private static class cancelCompaction_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<cancelCompaction_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, cancelCompaction_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -27358,8 +28006,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, cancelCompaction_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -27371,6 +28019,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class cancelCompaction_result implements org.apache.thrift.TBase<cancelCompaction_result, cancelCompaction_result._Fields>, java.io.Serializable, Cloneable, Comparable<cancelCompaction_result>   {
@@ -27380,11 +28031,8 @@
     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 cancelCompaction_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new cancelCompaction_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new cancelCompaction_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new cancelCompaction_resultTupleSchemeFactory();
 
     public AccumuloSecurityException ouch1; // required
     public TableNotFoundException ouch2; // required
@@ -27396,10 +28044,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -27426,21 +28074,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -27449,22 +28097,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(cancelCompaction_result.class, metaDataMap);
     }
 
@@ -27580,7 +28228,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -27609,7 +28257,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -27621,13 +28269,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -27638,11 +28286,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof cancelCompaction_result)
@@ -27653,6 +28301,8 @@
     public boolean equals(cancelCompaction_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -27686,24 +28336,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -27714,7 +28361,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -27724,7 +28371,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -27734,7 +28381,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -27752,16 +28399,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("cancelCompaction_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("cancelCompaction_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -27804,7 +28451,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -27812,13 +28459,13 @@
       }
     }
 
-    private static class cancelCompaction_resultStandardSchemeFactory implements SchemeFactory {
+    private static class cancelCompaction_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public cancelCompaction_resultStandardScheme getScheme() {
         return new cancelCompaction_resultStandardScheme();
       }
     }
 
-    private static class cancelCompaction_resultStandardScheme extends StandardScheme<cancelCompaction_result> {
+    private static class cancelCompaction_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<cancelCompaction_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, cancelCompaction_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -27893,18 +28540,18 @@
 
     }
 
-    private static class cancelCompaction_resultTupleSchemeFactory implements SchemeFactory {
+    private static class cancelCompaction_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public cancelCompaction_resultTupleScheme getScheme() {
         return new cancelCompaction_resultTupleScheme();
       }
     }
 
-    private static class cancelCompaction_resultTupleScheme extends TupleScheme<cancelCompaction_result> {
+    private static class cancelCompaction_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<cancelCompaction_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, cancelCompaction_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -27928,8 +28575,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, cancelCompaction_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloSecurityException();
           struct.ouch1.read(iprot);
@@ -27948,6 +28595,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createTable_args implements org.apache.thrift.TBase<createTable_args, createTable_args._Fields>, java.io.Serializable, Cloneable, Comparable<createTable_args>   {
@@ -27958,14 +28608,11 @@
     private static final org.apache.thrift.protocol.TField VERSIONING_ITER_FIELD_DESC = new org.apache.thrift.protocol.TField("versioningIter", org.apache.thrift.protocol.TType.BOOL, (short)3);
     private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", 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 createTable_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createTable_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createTable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createTable_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public boolean versioningIter; // required
     /**
      * 
@@ -27984,10 +28631,10 @@
        */
       TYPE((short)4, "type");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -28016,21 +28663,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -28039,7 +28686,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -28047,9 +28694,9 @@
     // isset id assignments
     private static final int __VERSIONINGITER_ISSET_ID = 0;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -28058,7 +28705,7 @@
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
       tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TimeType.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createTable_args.class, metaDataMap);
     }
 
@@ -28066,8 +28713,8 @@
     }
 
     public createTable_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       boolean versioningIter,
       TimeType type)
     {
@@ -28114,16 +28761,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createTable_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public createTable_args setLogin(ByteBuffer login) {
+    public createTable_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -28143,11 +28790,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public createTable_args setTableName(String tableName) {
+    public createTable_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -28178,16 +28825,16 @@
     }
 
     public void unsetVersioningIter() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __VERSIONINGITER_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __VERSIONINGITER_ISSET_ID);
     }
 
     /** Returns true if field versioningIter is set (has been assigned a value) and false otherwise */
     public boolean isSetVersioningIter() {
-      return EncodingUtils.testBit(__isset_bitfield, __VERSIONINGITER_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __VERSIONINGITER_ISSET_ID);
     }
 
     public void setVersioningIterIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __VERSIONINGITER_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __VERSIONINGITER_ISSET_ID, value);
     }
 
     /**
@@ -28222,13 +28869,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -28236,7 +28887,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -28244,7 +28895,7 @@
         if (value == null) {
           unsetVersioningIter();
         } else {
-          setVersioningIter((Boolean)value);
+          setVersioningIter((java.lang.Boolean)value);
         }
         break;
 
@@ -28259,7 +28910,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -28274,13 +28925,13 @@
         return getType();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -28293,11 +28944,11 @@
       case TYPE:
         return isSetType();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createTable_args)
@@ -28308,6 +28959,8 @@
     public boolean equals(createTable_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -28350,29 +29003,23 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_versioningIter = true;
-      list.add(present_versioningIter);
-      if (present_versioningIter)
-        list.add(versioningIter);
+      hashCode = hashCode * 8191 + ((versioningIter) ? 131071 : 524287);
 
-      boolean present_type = true && (isSetType());
-      list.add(present_type);
-      if (present_type)
-        list.add(type.getValue());
+      hashCode = hashCode * 8191 + ((isSetType()) ? 131071 : 524287);
+      if (isSetType())
+        hashCode = hashCode * 8191 + type.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -28383,7 +29030,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -28393,7 +29040,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -28403,7 +29050,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetVersioningIter()).compareTo(other.isSetVersioningIter());
+      lastComparison = java.lang.Boolean.valueOf(isSetVersioningIter()).compareTo(other.isSetVersioningIter());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -28413,7 +29060,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType());
+      lastComparison = java.lang.Boolean.valueOf(isSetType()).compareTo(other.isSetType());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -28431,16 +29078,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createTable_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createTable_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -28487,7 +29134,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -28497,13 +29144,13 @@
       }
     }
 
-    private static class createTable_argsStandardSchemeFactory implements SchemeFactory {
+    private static class createTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createTable_argsStandardScheme getScheme() {
         return new createTable_argsStandardScheme();
       }
     }
 
-    private static class createTable_argsStandardScheme extends StandardScheme<createTable_args> {
+    private static class createTable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createTable_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createTable_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -28586,18 +29233,18 @@
 
     }
 
-    private static class createTable_argsTupleSchemeFactory implements SchemeFactory {
+    private static class createTable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createTable_argsTupleScheme getScheme() {
         return new createTable_argsTupleScheme();
       }
     }
 
-    private static class createTable_argsTupleScheme extends TupleScheme<createTable_args> {
+    private static class createTable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createTable_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -28627,8 +29274,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -28648,6 +29295,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createTable_result implements org.apache.thrift.TBase<createTable_result, createTable_result._Fields>, java.io.Serializable, Cloneable, Comparable<createTable_result>   {
@@ -28657,11 +29307,8 @@
     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 createTable_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createTable_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createTable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createTable_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -28673,10 +29320,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -28703,21 +29350,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -28726,22 +29373,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableExistsException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createTable_result.class, metaDataMap);
     }
 
@@ -28857,7 +29504,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -28886,7 +29533,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -28898,13 +29545,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -28915,11 +29562,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createTable_result)
@@ -28930,6 +29577,8 @@
     public boolean equals(createTable_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -28963,24 +29612,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -28991,7 +29637,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -29001,7 +29647,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -29011,7 +29657,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -29029,16 +29675,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createTable_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createTable_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -29081,7 +29727,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -29089,13 +29735,13 @@
       }
     }
 
-    private static class createTable_resultStandardSchemeFactory implements SchemeFactory {
+    private static class createTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createTable_resultStandardScheme getScheme() {
         return new createTable_resultStandardScheme();
       }
     }
 
-    private static class createTable_resultStandardScheme extends StandardScheme<createTable_result> {
+    private static class createTable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createTable_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createTable_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -29170,18 +29816,18 @@
 
     }
 
-    private static class createTable_resultTupleSchemeFactory implements SchemeFactory {
+    private static class createTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createTable_resultTupleScheme getScheme() {
         return new createTable_resultTupleScheme();
       }
     }
 
-    private static class createTable_resultTupleScheme extends TupleScheme<createTable_result> {
+    private static class createTable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createTable_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -29205,8 +29851,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -29225,6 +29871,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class deleteTable_args implements org.apache.thrift.TBase<deleteTable_args, deleteTable_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteTable_args>   {
@@ -29233,24 +29882,21 @@
     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 TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", 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 deleteTable_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new deleteTable_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteTable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteTable_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // 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"),
       TABLE_NAME((short)2, "tableName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -29275,21 +29921,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -29298,20 +29944,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteTable_args.class, metaDataMap);
     }
 
@@ -29319,8 +29965,8 @@
     }
 
     public deleteTable_args(
-      ByteBuffer login,
-      String tableName)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -29354,16 +30000,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public deleteTable_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public deleteTable_args setLogin(ByteBuffer login) {
+    public deleteTable_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -29383,11 +30029,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public deleteTable_args setTableName(String tableName) {
+    public deleteTable_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -29407,13 +30053,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -29421,14 +30071,14 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -29437,13 +30087,13 @@
         return getTableName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -29452,11 +30102,11 @@
       case TABLE_NAME:
         return isSetTableName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof deleteTable_args)
@@ -29467,6 +30117,8 @@
     public boolean equals(deleteTable_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -29491,19 +30143,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -29514,7 +30164,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -29524,7 +30174,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -29542,16 +30192,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("deleteTable_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteTable_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -29586,7 +30236,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -29594,13 +30244,13 @@
       }
     }
 
-    private static class deleteTable_argsStandardSchemeFactory implements SchemeFactory {
+    private static class deleteTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteTable_argsStandardScheme getScheme() {
         return new deleteTable_argsStandardScheme();
       }
     }
 
-    private static class deleteTable_argsStandardScheme extends StandardScheme<deleteTable_args> {
+    private static class deleteTable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteTable_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, deleteTable_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -29659,18 +30309,18 @@
 
     }
 
-    private static class deleteTable_argsTupleSchemeFactory implements SchemeFactory {
+    private static class deleteTable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteTable_argsTupleScheme getScheme() {
         return new deleteTable_argsTupleScheme();
       }
     }
 
-    private static class deleteTable_argsTupleScheme extends TupleScheme<deleteTable_args> {
+    private static class deleteTable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteTable_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, deleteTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -29688,8 +30338,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, deleteTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -29701,6 +30351,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class deleteTable_result implements org.apache.thrift.TBase<deleteTable_result, deleteTable_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteTable_result>   {
@@ -29710,11 +30363,8 @@
     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 deleteTable_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new deleteTable_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteTable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteTable_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -29726,10 +30376,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -29756,21 +30406,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -29779,22 +30429,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteTable_result.class, metaDataMap);
     }
 
@@ -29910,7 +30560,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -29939,7 +30589,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -29951,13 +30601,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -29968,11 +30618,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof deleteTable_result)
@@ -29983,6 +30633,8 @@
     public boolean equals(deleteTable_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -30016,24 +30668,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -30044,7 +30693,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -30054,7 +30703,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -30064,7 +30713,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -30082,16 +30731,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("deleteTable_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteTable_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -30134,7 +30783,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -30142,13 +30791,13 @@
       }
     }
 
-    private static class deleteTable_resultStandardSchemeFactory implements SchemeFactory {
+    private static class deleteTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteTable_resultStandardScheme getScheme() {
         return new deleteTable_resultStandardScheme();
       }
     }
 
-    private static class deleteTable_resultStandardScheme extends StandardScheme<deleteTable_result> {
+    private static class deleteTable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteTable_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, deleteTable_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -30223,18 +30872,18 @@
 
     }
 
-    private static class deleteTable_resultTupleSchemeFactory implements SchemeFactory {
+    private static class deleteTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteTable_resultTupleScheme getScheme() {
         return new deleteTable_resultTupleScheme();
       }
     }
 
-    private static class deleteTable_resultTupleScheme extends TupleScheme<deleteTable_result> {
+    private static class deleteTable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteTable_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, deleteTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -30258,8 +30907,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, deleteTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -30278,6 +30927,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class deleteRows_args implements org.apache.thrift.TBase<deleteRows_args, deleteRows_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteRows_args>   {
@@ -30288,16 +30940,13 @@
     private static final org.apache.thrift.protocol.TField START_ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("startRow", org.apache.thrift.protocol.TType.STRING, (short)3);
     private static final org.apache.thrift.protocol.TField END_ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("endRow", 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 deleteRows_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new deleteRows_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteRows_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteRows_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public ByteBuffer startRow; // required
-    public ByteBuffer endRow; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.nio.ByteBuffer startRow; // required
+    public java.nio.ByteBuffer endRow; // 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 {
@@ -30306,10 +30955,10 @@
       START_ROW((short)3, "startRow"),
       END_ROW((short)4, "endRow");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -30338,21 +30987,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -30361,15 +31010,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -30378,7 +31027,7 @@
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
       tmpMap.put(_Fields.END_ROW, new org.apache.thrift.meta_data.FieldMetaData("endRow", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteRows_args.class, metaDataMap);
     }
 
@@ -30386,10 +31035,10 @@
     }
 
     public deleteRows_args(
-      ByteBuffer login,
-      String tableName,
-      ByteBuffer startRow,
-      ByteBuffer endRow)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.nio.ByteBuffer startRow,
+      java.nio.ByteBuffer endRow)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -30433,16 +31082,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public deleteRows_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public deleteRows_args setLogin(ByteBuffer login) {
+    public deleteRows_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -30462,11 +31111,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public deleteRows_args setTableName(String tableName) {
+    public deleteRows_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -30491,16 +31140,16 @@
       return startRow == null ? null : startRow.array();
     }
 
-    public ByteBuffer bufferForStartRow() {
+    public java.nio.ByteBuffer bufferForStartRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(startRow);
     }
 
     public deleteRows_args setStartRow(byte[] startRow) {
-      this.startRow = startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(startRow, startRow.length));
+      this.startRow = startRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(startRow.clone());
       return this;
     }
 
-    public deleteRows_args setStartRow(ByteBuffer startRow) {
+    public deleteRows_args setStartRow(java.nio.ByteBuffer startRow) {
       this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       return this;
     }
@@ -30525,16 +31174,16 @@
       return endRow == null ? null : endRow.array();
     }
 
-    public ByteBuffer bufferForEndRow() {
+    public java.nio.ByteBuffer bufferForEndRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     public deleteRows_args setEndRow(byte[] endRow) {
-      this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
+      this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
       return this;
     }
 
-    public deleteRows_args setEndRow(ByteBuffer endRow) {
+    public deleteRows_args setEndRow(java.nio.ByteBuffer endRow) {
       this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       return this;
     }
@@ -30554,13 +31203,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -30568,7 +31221,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -30576,7 +31229,11 @@
         if (value == null) {
           unsetStartRow();
         } else {
-          setStartRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setStartRow((byte[])value);
+          } else {
+            setStartRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -30584,14 +31241,18 @@
         if (value == null) {
           unsetEndRow();
         } else {
-          setEndRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setEndRow((byte[])value);
+          } else {
+            setEndRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -30606,13 +31267,13 @@
         return getEndRow();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -30625,11 +31286,11 @@
       case END_ROW:
         return isSetEndRow();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof deleteRows_args)
@@ -30640,6 +31301,8 @@
     public boolean equals(deleteRows_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -30682,29 +31345,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_startRow = true && (isSetStartRow());
-      list.add(present_startRow);
-      if (present_startRow)
-        list.add(startRow);
+      hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
+      if (isSetStartRow())
+        hashCode = hashCode * 8191 + startRow.hashCode();
 
-      boolean present_endRow = true && (isSetEndRow());
-      list.add(present_endRow);
-      if (present_endRow)
-        list.add(endRow);
+      hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
+      if (isSetEndRow())
+        hashCode = hashCode * 8191 + endRow.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -30715,7 +31374,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -30725,7 +31384,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -30735,7 +31394,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -30745,7 +31404,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -30763,16 +31422,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("deleteRows_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteRows_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -30823,7 +31482,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -30831,13 +31490,13 @@
       }
     }
 
-    private static class deleteRows_argsStandardSchemeFactory implements SchemeFactory {
+    private static class deleteRows_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteRows_argsStandardScheme getScheme() {
         return new deleteRows_argsStandardScheme();
       }
     }
 
-    private static class deleteRows_argsStandardScheme extends StandardScheme<deleteRows_args> {
+    private static class deleteRows_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteRows_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, deleteRows_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -30922,18 +31581,18 @@
 
     }
 
-    private static class deleteRows_argsTupleSchemeFactory implements SchemeFactory {
+    private static class deleteRows_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteRows_argsTupleScheme getScheme() {
         return new deleteRows_argsTupleScheme();
       }
     }
 
-    private static class deleteRows_argsTupleScheme extends TupleScheme<deleteRows_args> {
+    private static class deleteRows_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteRows_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, deleteRows_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -30963,8 +31622,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, deleteRows_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -30984,6 +31643,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class deleteRows_result implements org.apache.thrift.TBase<deleteRows_result, deleteRows_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteRows_result>   {
@@ -30993,11 +31655,8 @@
     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 deleteRows_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new deleteRows_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteRows_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteRows_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -31009,10 +31668,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -31039,21 +31698,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -31062,22 +31721,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteRows_result.class, metaDataMap);
     }
 
@@ -31193,7 +31852,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -31222,7 +31881,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -31234,13 +31893,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -31251,11 +31910,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof deleteRows_result)
@@ -31266,6 +31925,8 @@
     public boolean equals(deleteRows_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -31299,24 +31960,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -31327,7 +31985,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -31337,7 +31995,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -31347,7 +32005,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -31365,16 +32023,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("deleteRows_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteRows_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -31417,7 +32075,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -31425,13 +32083,13 @@
       }
     }
 
-    private static class deleteRows_resultStandardSchemeFactory implements SchemeFactory {
+    private static class deleteRows_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteRows_resultStandardScheme getScheme() {
         return new deleteRows_resultStandardScheme();
       }
     }
 
-    private static class deleteRows_resultStandardScheme extends StandardScheme<deleteRows_result> {
+    private static class deleteRows_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteRows_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, deleteRows_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -31506,18 +32164,18 @@
 
     }
 
-    private static class deleteRows_resultTupleSchemeFactory implements SchemeFactory {
+    private static class deleteRows_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteRows_resultTupleScheme getScheme() {
         return new deleteRows_resultTupleScheme();
       }
     }
 
-    private static class deleteRows_resultTupleScheme extends TupleScheme<deleteRows_result> {
+    private static class deleteRows_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteRows_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, deleteRows_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -31541,8 +32199,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, deleteRows_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -31561,6 +32219,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class exportTable_args implements org.apache.thrift.TBase<exportTable_args, exportTable_args._Fields>, java.io.Serializable, Cloneable, Comparable<exportTable_args>   {
@@ -31570,15 +32231,12 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField EXPORT_DIR_FIELD_DESC = new org.apache.thrift.protocol.TField("exportDir", 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 exportTable_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new exportTable_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new exportTable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new exportTable_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public String exportDir; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.lang.String exportDir; // 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 {
@@ -31586,10 +32244,10 @@
       TABLE_NAME((short)2, "tableName"),
       EXPORT_DIR((short)3, "exportDir");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -31616,21 +32274,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -31639,22 +32297,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.EXPORT_DIR, new org.apache.thrift.meta_data.FieldMetaData("exportDir", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(exportTable_args.class, metaDataMap);
     }
 
@@ -31662,9 +32320,9 @@
     }
 
     public exportTable_args(
-      ByteBuffer login,
-      String tableName,
-      String exportDir)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.lang.String exportDir)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -31703,16 +32361,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public exportTable_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public exportTable_args setLogin(ByteBuffer login) {
+    public exportTable_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -31732,11 +32390,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public exportTable_args setTableName(String tableName) {
+    public exportTable_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -31756,11 +32414,11 @@
       }
     }
 
-    public String getExportDir() {
+    public java.lang.String getExportDir() {
       return this.exportDir;
     }
 
-    public exportTable_args setExportDir(String exportDir) {
+    public exportTable_args setExportDir(java.lang.String exportDir) {
       this.exportDir = exportDir;
       return this;
     }
@@ -31780,13 +32438,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -31794,7 +32456,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -31802,14 +32464,14 @@
         if (value == null) {
           unsetExportDir();
         } else {
-          setExportDir((String)value);
+          setExportDir((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -31821,13 +32483,13 @@
         return getExportDir();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -31838,11 +32500,11 @@
       case EXPORT_DIR:
         return isSetExportDir();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof exportTable_args)
@@ -31853,6 +32515,8 @@
     public boolean equals(exportTable_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -31886,24 +32550,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_exportDir = true && (isSetExportDir());
-      list.add(present_exportDir);
-      if (present_exportDir)
-        list.add(exportDir);
+      hashCode = hashCode * 8191 + ((isSetExportDir()) ? 131071 : 524287);
+      if (isSetExportDir())
+        hashCode = hashCode * 8191 + exportDir.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -31914,7 +32575,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -31924,7 +32585,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -31934,7 +32595,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetExportDir()).compareTo(other.isSetExportDir());
+      lastComparison = java.lang.Boolean.valueOf(isSetExportDir()).compareTo(other.isSetExportDir());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -31952,16 +32613,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("exportTable_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("exportTable_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -32004,7 +32665,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -32012,13 +32673,13 @@
       }
     }
 
-    private static class exportTable_argsStandardSchemeFactory implements SchemeFactory {
+    private static class exportTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public exportTable_argsStandardScheme getScheme() {
         return new exportTable_argsStandardScheme();
       }
     }
 
-    private static class exportTable_argsStandardScheme extends StandardScheme<exportTable_args> {
+    private static class exportTable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<exportTable_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, exportTable_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -32090,18 +32751,18 @@
 
     }
 
-    private static class exportTable_argsTupleSchemeFactory implements SchemeFactory {
+    private static class exportTable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public exportTable_argsTupleScheme getScheme() {
         return new exportTable_argsTupleScheme();
       }
     }
 
-    private static class exportTable_argsTupleScheme extends TupleScheme<exportTable_args> {
+    private static class exportTable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<exportTable_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, exportTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -32125,8 +32786,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, exportTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -32142,6 +32803,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class exportTable_result implements org.apache.thrift.TBase<exportTable_result, exportTable_result._Fields>, java.io.Serializable, Cloneable, Comparable<exportTable_result>   {
@@ -32151,11 +32815,8 @@
     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 exportTable_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new exportTable_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new exportTable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new exportTable_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -32167,10 +32828,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -32197,21 +32858,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -32220,22 +32881,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(exportTable_result.class, metaDataMap);
     }
 
@@ -32351,7 +33012,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -32380,7 +33041,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -32392,13 +33053,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -32409,11 +33070,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof exportTable_result)
@@ -32424,6 +33085,8 @@
     public boolean equals(exportTable_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -32457,24 +33120,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -32485,7 +33145,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -32495,7 +33155,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -32505,7 +33165,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -32523,16 +33183,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("exportTable_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("exportTable_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -32575,7 +33235,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -32583,13 +33243,13 @@
       }
     }
 
-    private static class exportTable_resultStandardSchemeFactory implements SchemeFactory {
+    private static class exportTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public exportTable_resultStandardScheme getScheme() {
         return new exportTable_resultStandardScheme();
       }
     }
 
-    private static class exportTable_resultStandardScheme extends StandardScheme<exportTable_result> {
+    private static class exportTable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<exportTable_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, exportTable_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -32664,18 +33324,18 @@
 
     }
 
-    private static class exportTable_resultTupleSchemeFactory implements SchemeFactory {
+    private static class exportTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public exportTable_resultTupleScheme getScheme() {
         return new exportTable_resultTupleScheme();
       }
     }
 
-    private static class exportTable_resultTupleScheme extends TupleScheme<exportTable_result> {
+    private static class exportTable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<exportTable_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, exportTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -32699,8 +33359,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, exportTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -32719,6 +33379,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class flushTable_args implements org.apache.thrift.TBase<flushTable_args, flushTable_args._Fields>, java.io.Serializable, Cloneable, Comparable<flushTable_args>   {
@@ -32730,16 +33393,13 @@
     private static final org.apache.thrift.protocol.TField END_ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("endRow", org.apache.thrift.protocol.TType.STRING, (short)4);
     private static final org.apache.thrift.protocol.TField WAIT_FIELD_DESC = new org.apache.thrift.protocol.TField("wait", org.apache.thrift.protocol.TType.BOOL, (short)5);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new flushTable_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new flushTable_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new flushTable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new flushTable_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public ByteBuffer startRow; // required
-    public ByteBuffer endRow; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.nio.ByteBuffer startRow; // required
+    public java.nio.ByteBuffer endRow; // required
     public boolean wait; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -32750,10 +33410,10 @@
       END_ROW((short)4, "endRow"),
       WAIT((short)5, "wait");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -32784,21 +33444,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -32807,7 +33467,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -32815,9 +33475,9 @@
     // isset id assignments
     private static final int __WAIT_ISSET_ID = 0;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -32828,7 +33488,7 @@
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
       tmpMap.put(_Fields.WAIT, new org.apache.thrift.meta_data.FieldMetaData("wait", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(flushTable_args.class, metaDataMap);
     }
 
@@ -32836,10 +33496,10 @@
     }
 
     public flushTable_args(
-      ByteBuffer login,
-      String tableName,
-      ByteBuffer startRow,
-      ByteBuffer endRow,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.nio.ByteBuffer startRow,
+      java.nio.ByteBuffer endRow,
       boolean wait)
     {
       this();
@@ -32890,16 +33550,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public flushTable_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public flushTable_args setLogin(ByteBuffer login) {
+    public flushTable_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -32919,11 +33579,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public flushTable_args setTableName(String tableName) {
+    public flushTable_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -32948,16 +33608,16 @@
       return startRow == null ? null : startRow.array();
     }
 
-    public ByteBuffer bufferForStartRow() {
+    public java.nio.ByteBuffer bufferForStartRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(startRow);
     }
 
     public flushTable_args setStartRow(byte[] startRow) {
-      this.startRow = startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(startRow, startRow.length));
+      this.startRow = startRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(startRow.clone());
       return this;
     }
 
-    public flushTable_args setStartRow(ByteBuffer startRow) {
+    public flushTable_args setStartRow(java.nio.ByteBuffer startRow) {
       this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       return this;
     }
@@ -32982,16 +33642,16 @@
       return endRow == null ? null : endRow.array();
     }
 
-    public ByteBuffer bufferForEndRow() {
+    public java.nio.ByteBuffer bufferForEndRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     public flushTable_args setEndRow(byte[] endRow) {
-      this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
+      this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
       return this;
     }
 
-    public flushTable_args setEndRow(ByteBuffer endRow) {
+    public flushTable_args setEndRow(java.nio.ByteBuffer endRow) {
       this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       return this;
     }
@@ -33022,25 +33682,29 @@
     }
 
     public void unsetWait() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __WAIT_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __WAIT_ISSET_ID);
     }
 
     /** Returns true if field wait is set (has been assigned a value) and false otherwise */
     public boolean isSetWait() {
-      return EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
     }
 
     public void setWaitIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -33048,7 +33712,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -33056,7 +33720,11 @@
         if (value == null) {
           unsetStartRow();
         } else {
-          setStartRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setStartRow((byte[])value);
+          } else {
+            setStartRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -33064,7 +33732,11 @@
         if (value == null) {
           unsetEndRow();
         } else {
-          setEndRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setEndRow((byte[])value);
+          } else {
+            setEndRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -33072,14 +33744,14 @@
         if (value == null) {
           unsetWait();
         } else {
-          setWait((Boolean)value);
+          setWait((java.lang.Boolean)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -33097,13 +33769,13 @@
         return isWait();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -33118,11 +33790,11 @@
       case WAIT:
         return isSetWait();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof flushTable_args)
@@ -33133,6 +33805,8 @@
     public boolean equals(flushTable_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -33184,34 +33858,27 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_startRow = true && (isSetStartRow());
-      list.add(present_startRow);
-      if (present_startRow)
-        list.add(startRow);
+      hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
+      if (isSetStartRow())
+        hashCode = hashCode * 8191 + startRow.hashCode();
 
-      boolean present_endRow = true && (isSetEndRow());
-      list.add(present_endRow);
-      if (present_endRow)
-        list.add(endRow);
+      hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
+      if (isSetEndRow())
+        hashCode = hashCode * 8191 + endRow.hashCode();
 
-      boolean present_wait = true;
-      list.add(present_wait);
-      if (present_wait)
-        list.add(wait);
+      hashCode = hashCode * 8191 + ((wait) ? 131071 : 524287);
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -33222,7 +33889,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -33232,7 +33899,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -33242,7 +33909,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -33252,7 +33919,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -33262,7 +33929,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
+      lastComparison = java.lang.Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -33280,16 +33947,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("flushTable_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("flushTable_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -33344,7 +34011,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -33354,13 +34021,13 @@
       }
     }
 
-    private static class flushTable_argsStandardSchemeFactory implements SchemeFactory {
+    private static class flushTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public flushTable_argsStandardScheme getScheme() {
         return new flushTable_argsStandardScheme();
       }
     }
 
-    private static class flushTable_argsStandardScheme extends StandardScheme<flushTable_args> {
+    private static class flushTable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<flushTable_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, flushTable_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -33456,18 +34123,18 @@
 
     }
 
-    private static class flushTable_argsTupleSchemeFactory implements SchemeFactory {
+    private static class flushTable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public flushTable_argsTupleScheme getScheme() {
         return new flushTable_argsTupleScheme();
       }
     }
 
-    private static class flushTable_argsTupleScheme extends TupleScheme<flushTable_args> {
+    private static class flushTable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<flushTable_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, flushTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -33503,8 +34170,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, flushTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(5);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(5);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -33528,6 +34195,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class flushTable_result implements org.apache.thrift.TBase<flushTable_result, flushTable_result._Fields>, java.io.Serializable, Cloneable, Comparable<flushTable_result>   {
@@ -33537,11 +34207,8 @@
     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 flushTable_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new flushTable_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new flushTable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new flushTable_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -33553,10 +34220,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -33583,21 +34250,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -33606,22 +34273,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(flushTable_result.class, metaDataMap);
     }
 
@@ -33737,7 +34404,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -33766,7 +34433,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -33778,13 +34445,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -33795,11 +34462,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof flushTable_result)
@@ -33810,6 +34477,8 @@
     public boolean equals(flushTable_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -33843,24 +34512,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -33871,7 +34537,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -33881,7 +34547,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -33891,7 +34557,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -33909,16 +34575,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("flushTable_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("flushTable_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -33961,7 +34627,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -33969,13 +34635,13 @@
       }
     }
 
-    private static class flushTable_resultStandardSchemeFactory implements SchemeFactory {
+    private static class flushTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public flushTable_resultStandardScheme getScheme() {
         return new flushTable_resultStandardScheme();
       }
     }
 
-    private static class flushTable_resultStandardScheme extends StandardScheme<flushTable_result> {
+    private static class flushTable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<flushTable_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, flushTable_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -34050,18 +34716,18 @@
 
     }
 
-    private static class flushTable_resultTupleSchemeFactory implements SchemeFactory {
+    private static class flushTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public flushTable_resultTupleScheme getScheme() {
         return new flushTable_resultTupleScheme();
       }
     }
 
-    private static class flushTable_resultTupleScheme extends TupleScheme<flushTable_result> {
+    private static class flushTable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<flushTable_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, flushTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -34085,8 +34751,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, flushTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -34105,6 +34771,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getDiskUsage_args implements org.apache.thrift.TBase<getDiskUsage_args, getDiskUsage_args._Fields>, java.io.Serializable, Cloneable, Comparable<getDiskUsage_args>   {
@@ -34113,24 +34782,21 @@
     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 TABLES_FIELD_DESC = new org.apache.thrift.protocol.TField("tables", org.apache.thrift.protocol.TType.SET, (short)2);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new getDiskUsage_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getDiskUsage_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getDiskUsage_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getDiskUsage_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public Set<String> tables; // required
+    public java.nio.ByteBuffer login; // required
+    public java.util.Set<java.lang.String> tables; // 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"),
       TABLES((short)2, "tables");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -34155,21 +34821,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -34178,21 +34844,21 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLES, new org.apache.thrift.meta_data.FieldMetaData("tables", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
               new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDiskUsage_args.class, metaDataMap);
     }
 
@@ -34200,8 +34866,8 @@
     }
 
     public getDiskUsage_args(
-      ByteBuffer login,
-      Set<String> tables)
+      java.nio.ByteBuffer login,
+      java.util.Set<java.lang.String> tables)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -34216,7 +34882,7 @@
         this.login = org.apache.thrift.TBaseHelper.copyBinary(other.login);
       }
       if (other.isSetTables()) {
-        Set<String> __this__tables = new HashSet<String>(other.tables);
+        java.util.Set<java.lang.String> __this__tables = new java.util.HashSet<java.lang.String>(other.tables);
         this.tables = __this__tables;
       }
     }
@@ -34236,16 +34902,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getDiskUsage_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getDiskUsage_args setLogin(ByteBuffer login) {
+    public getDiskUsage_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -34269,22 +34935,22 @@
       return (this.tables == null) ? 0 : this.tables.size();
     }
 
-    public java.util.Iterator<String> getTablesIterator() {
+    public java.util.Iterator<java.lang.String> getTablesIterator() {
       return (this.tables == null) ? null : this.tables.iterator();
     }
 
-    public void addToTables(String elem) {
+    public void addToTables(java.lang.String elem) {
       if (this.tables == null) {
-        this.tables = new HashSet<String>();
+        this.tables = new java.util.HashSet<java.lang.String>();
       }
       this.tables.add(elem);
     }
 
-    public Set<String> getTables() {
+    public java.util.Set<java.lang.String> getTables() {
       return this.tables;
     }
 
-    public getDiskUsage_args setTables(Set<String> tables) {
+    public getDiskUsage_args setTables(java.util.Set<java.lang.String> tables) {
       this.tables = tables;
       return this;
     }
@@ -34304,13 +34970,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -34318,14 +34988,14 @@
         if (value == null) {
           unsetTables();
         } else {
-          setTables((Set<String>)value);
+          setTables((java.util.Set<java.lang.String>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -34334,13 +35004,13 @@
         return getTables();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -34349,11 +35019,11 @@
       case TABLES:
         return isSetTables();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getDiskUsage_args)
@@ -34364,6 +35034,8 @@
     public boolean equals(getDiskUsage_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -34388,19 +35060,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tables = true && (isSetTables());
-      list.add(present_tables);
-      if (present_tables)
-        list.add(tables);
+      hashCode = hashCode * 8191 + ((isSetTables()) ? 131071 : 524287);
+      if (isSetTables())
+        hashCode = hashCode * 8191 + tables.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -34411,7 +35081,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -34421,7 +35091,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTables()).compareTo(other.isSetTables());
+      lastComparison = java.lang.Boolean.valueOf(isSetTables()).compareTo(other.isSetTables());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -34439,16 +35109,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getDiskUsage_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getDiskUsage_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -34483,7 +35153,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -34491,13 +35161,13 @@
       }
     }
 
-    private static class getDiskUsage_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getDiskUsage_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getDiskUsage_argsStandardScheme getScheme() {
         return new getDiskUsage_argsStandardScheme();
       }
     }
 
-    private static class getDiskUsage_argsStandardScheme extends StandardScheme<getDiskUsage_args> {
+    private static class getDiskUsage_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getDiskUsage_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getDiskUsage_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -34521,8 +35191,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set224 = iprot.readSetBegin();
-                  struct.tables = new HashSet<String>(2*_set224.size);
-                  String _elem225;
+                  struct.tables = new java.util.HashSet<java.lang.String>(2*_set224.size);
+                  java.lang.String _elem225;
                   for (int _i226 = 0; _i226 < _set224.size; ++_i226)
                   {
                     _elem225 = iprot.readString();
@@ -34559,7 +35229,7 @@
           oprot.writeFieldBegin(TABLES_FIELD_DESC);
           {
             oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.tables.size()));
-            for (String _iter227 : struct.tables)
+            for (java.lang.String _iter227 : struct.tables)
             {
               oprot.writeString(_iter227);
             }
@@ -34573,18 +35243,18 @@
 
     }
 
-    private static class getDiskUsage_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getDiskUsage_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getDiskUsage_argsTupleScheme getScheme() {
         return new getDiskUsage_argsTupleScheme();
       }
     }
 
-    private static class getDiskUsage_argsTupleScheme extends TupleScheme<getDiskUsage_args> {
+    private static class getDiskUsage_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getDiskUsage_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getDiskUsage_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -34598,7 +35268,7 @@
         if (struct.isSetTables()) {
           {
             oprot.writeI32(struct.tables.size());
-            for (String _iter228 : struct.tables)
+            for (java.lang.String _iter228 : struct.tables)
             {
               oprot.writeString(_iter228);
             }
@@ -34608,8 +35278,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getDiskUsage_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -34617,8 +35287,8 @@
         if (incoming.get(1)) {
           {
             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);
-            String _elem230;
+            struct.tables = new java.util.HashSet<java.lang.String>(2*_set229.size);
+            java.lang.String _elem230;
             for (int _i231 = 0; _i231 < _set229.size; ++_i231)
             {
               _elem230 = iprot.readString();
@@ -34630,6 +35300,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getDiskUsage_result implements org.apache.thrift.TBase<getDiskUsage_result, getDiskUsage_result._Fields>, java.io.Serializable, Cloneable, Comparable<getDiskUsage_result>   {
@@ -34640,13 +35313,10 @@
     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 getDiskUsage_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getDiskUsage_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getDiskUsage_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getDiskUsage_resultTupleSchemeFactory();
 
-    public List<DiskUsage> success; // required
+    public java.util.List<DiskUsage> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -34658,10 +35328,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -34690,21 +35360,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -34713,25 +35383,25 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, DiskUsage.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDiskUsage_result.class, metaDataMap);
     }
 
@@ -34739,7 +35409,7 @@
     }
 
     public getDiskUsage_result(
-      List<DiskUsage> success,
+      java.util.List<DiskUsage> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -34756,7 +35426,7 @@
      */
     public getDiskUsage_result(getDiskUsage_result other) {
       if (other.isSetSuccess()) {
-        List<DiskUsage> __this__success = new ArrayList<DiskUsage>(other.success.size());
+        java.util.List<DiskUsage> __this__success = new java.util.ArrayList<DiskUsage>(other.success.size());
         for (DiskUsage other_element : other.success) {
           __this__success.add(new DiskUsage(other_element));
         }
@@ -34795,16 +35465,16 @@
 
     public void addToSuccess(DiskUsage elem) {
       if (this.success == null) {
-        this.success = new ArrayList<DiskUsage>();
+        this.success = new java.util.ArrayList<DiskUsage>();
       }
       this.success.add(elem);
     }
 
-    public List<DiskUsage> getSuccess() {
+    public java.util.List<DiskUsage> getSuccess() {
       return this.success;
     }
 
-    public getDiskUsage_result setSuccess(List<DiskUsage> success) {
+    public getDiskUsage_result setSuccess(java.util.List<DiskUsage> success) {
       this.success = success;
       return this;
     }
@@ -34896,13 +35566,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((List<DiskUsage>)value);
+          setSuccess((java.util.List<DiskUsage>)value);
         }
         break;
 
@@ -34933,7 +35603,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -34948,13 +35618,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -34967,11 +35637,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getDiskUsage_result)
@@ -34982,6 +35652,8 @@
     public boolean equals(getDiskUsage_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -35024,29 +35696,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -35057,7 +35725,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -35067,7 +35735,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -35077,7 +35745,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -35087,7 +35755,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -35105,16 +35773,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getDiskUsage_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getDiskUsage_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -35165,7 +35833,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -35173,13 +35841,13 @@
       }
     }
 
-    private static class getDiskUsage_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getDiskUsage_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getDiskUsage_resultStandardScheme getScheme() {
         return new getDiskUsage_resultStandardScheme();
       }
     }
 
-    private static class getDiskUsage_resultStandardScheme extends StandardScheme<getDiskUsage_result> {
+    private static class getDiskUsage_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getDiskUsage_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getDiskUsage_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -35195,7 +35863,7 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                 {
                   org.apache.thrift.protocol.TList _list232 = iprot.readListBegin();
-                  struct.success = new ArrayList<DiskUsage>(_list232.size);
+                  struct.success = new java.util.ArrayList<DiskUsage>(_list232.size);
                   DiskUsage _elem233;
                   for (int _i234 = 0; _i234 < _list232.size; ++_i234)
                   {
@@ -35285,18 +35953,18 @@
 
     }
 
-    private static class getDiskUsage_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getDiskUsage_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getDiskUsage_resultTupleScheme getScheme() {
         return new getDiskUsage_resultTupleScheme();
       }
     }
 
-    private static class getDiskUsage_resultTupleScheme extends TupleScheme<getDiskUsage_result> {
+    private static class getDiskUsage_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getDiskUsage_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getDiskUsage_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -35332,12 +36000,12 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getDiskUsage_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           {
             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);
+            struct.success = new java.util.ArrayList<DiskUsage>(_list237.size);
             DiskUsage _elem238;
             for (int _i239 = 0; _i239 < _list237.size; ++_i239)
             {
@@ -35366,6 +36034,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getLocalityGroups_args implements org.apache.thrift.TBase<getLocalityGroups_args, getLocalityGroups_args._Fields>, java.io.Serializable, Cloneable, Comparable<getLocalityGroups_args>   {
@@ -35374,24 +36045,21 @@
     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 TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", 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 getLocalityGroups_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getLocalityGroups_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getLocalityGroups_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getLocalityGroups_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // 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"),
       TABLE_NAME((short)2, "tableName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -35416,21 +36084,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -35439,20 +36107,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getLocalityGroups_args.class, metaDataMap);
     }
 
@@ -35460,8 +36128,8 @@
     }
 
     public getLocalityGroups_args(
-      ByteBuffer login,
-      String tableName)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -35495,16 +36163,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getLocalityGroups_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getLocalityGroups_args setLogin(ByteBuffer login) {
+    public getLocalityGroups_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -35524,11 +36192,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public getLocalityGroups_args setTableName(String tableName) {
+    public getLocalityGroups_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -35548,13 +36216,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -35562,14 +36234,14 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -35578,13 +36250,13 @@
         return getTableName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -35593,11 +36265,11 @@
       case TABLE_NAME:
         return isSetTableName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getLocalityGroups_args)
@@ -35608,6 +36280,8 @@
     public boolean equals(getLocalityGroups_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -35632,19 +36306,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -35655,7 +36327,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -35665,7 +36337,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -35683,16 +36355,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getLocalityGroups_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getLocalityGroups_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -35727,7 +36399,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -35735,13 +36407,13 @@
       }
     }
 
-    private static class getLocalityGroups_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getLocalityGroups_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getLocalityGroups_argsStandardScheme getScheme() {
         return new getLocalityGroups_argsStandardScheme();
       }
     }
 
-    private static class getLocalityGroups_argsStandardScheme extends StandardScheme<getLocalityGroups_args> {
+    private static class getLocalityGroups_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getLocalityGroups_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getLocalityGroups_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -35800,18 +36472,18 @@
 
     }
 
-    private static class getLocalityGroups_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getLocalityGroups_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getLocalityGroups_argsTupleScheme getScheme() {
         return new getLocalityGroups_argsTupleScheme();
       }
     }
 
-    private static class getLocalityGroups_argsTupleScheme extends TupleScheme<getLocalityGroups_args> {
+    private static class getLocalityGroups_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getLocalityGroups_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getLocalityGroups_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -35829,8 +36501,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getLocalityGroups_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -35842,6 +36514,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getLocalityGroups_result implements org.apache.thrift.TBase<getLocalityGroups_result, getLocalityGroups_result._Fields>, java.io.Serializable, Cloneable, Comparable<getLocalityGroups_result>   {
@@ -35852,13 +36527,10 @@
     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 getLocalityGroups_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getLocalityGroups_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getLocalityGroups_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getLocalityGroups_resultTupleSchemeFactory();
 
-    public Map<String,Set<String>> success; // required
+    public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -35870,10 +36542,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -35902,21 +36574,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -35925,27 +36597,27 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getLocalityGroups_result.class, metaDataMap);
     }
 
@@ -35953,7 +36625,7 @@
     }
 
     public getLocalityGroups_result(
-      Map<String,Set<String>> success,
+      java.util.Map<java.lang.String,java.util.Set<java.lang.String>> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -35970,15 +36642,15 @@
      */
     public getLocalityGroups_result(getLocalityGroups_result other) {
       if (other.isSetSuccess()) {
-        Map<String,Set<String>> __this__success = new HashMap<String,Set<String>>(other.success.size());
-        for (Map.Entry<String, Set<String>> other_element : other.success.entrySet()) {
+        java.util.Map<java.lang.String,java.util.Set<java.lang.String>> __this__success = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>(other.success.size());
+        for (java.util.Map.Entry<java.lang.String, java.util.Set<java.lang.String>> other_element : other.success.entrySet()) {
 
-          String other_element_key = other_element.getKey();
-          Set<String> other_element_value = other_element.getValue();
+          java.lang.String other_element_key = other_element.getKey();
+          java.util.Set<java.lang.String> other_element_value = other_element.getValue();
 
-          String __this__success_copy_key = other_element_key;
+          java.lang.String __this__success_copy_key = other_element_key;
 
-          Set<String> __this__success_copy_value = new HashSet<String>(other_element_value);
+          java.util.Set<java.lang.String> __this__success_copy_value = new java.util.HashSet<java.lang.String>(other_element_value);
 
           __this__success.put(__this__success_copy_key, __this__success_copy_value);
         }
@@ -36011,18 +36683,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, Set<String> val) {
+    public void putToSuccess(java.lang.String key, java.util.Set<java.lang.String> val) {
       if (this.success == null) {
-        this.success = new HashMap<String,Set<String>>();
+        this.success = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,Set<String>> getSuccess() {
+    public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getSuccess() {
       return this.success;
     }
 
-    public getLocalityGroups_result setSuccess(Map<String,Set<String>> success) {
+    public getLocalityGroups_result setSuccess(java.util.Map<java.lang.String,java.util.Set<java.lang.String>> success) {
       this.success = success;
       return this;
     }
@@ -36114,13 +36786,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,Set<String>>)value);
+          setSuccess((java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)value);
         }
         break;
 
@@ -36151,7 +36823,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -36166,13 +36838,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -36185,11 +36857,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getLocalityGroups_result)
@@ -36200,6 +36872,8 @@
     public boolean equals(getLocalityGroups_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -36242,29 +36916,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -36275,7 +36945,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -36285,7 +36955,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -36295,7 +36965,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -36305,7 +36975,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -36323,16 +36993,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getLocalityGroups_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getLocalityGroups_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -36383,7 +37053,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -36391,13 +37061,13 @@
       }
     }
 
-    private static class getLocalityGroups_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getLocalityGroups_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getLocalityGroups_resultStandardScheme getScheme() {
         return new getLocalityGroups_resultStandardScheme();
       }
     }
 
-    private static class getLocalityGroups_resultStandardScheme extends StandardScheme<getLocalityGroups_result> {
+    private static class getLocalityGroups_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getLocalityGroups_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getLocalityGroups_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -36413,16 +37083,16 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map240 = iprot.readMapBegin();
-                  struct.success = new HashMap<String,Set<String>>(2*_map240.size);
-                  String _key241;
-                  Set<String> _val242;
+                  struct.success = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>(2*_map240.size);
+                  java.lang.String _key241;
+                  java.util.Set<java.lang.String> _val242;
                   for (int _i243 = 0; _i243 < _map240.size; ++_i243)
                   {
                     _key241 = iprot.readString();
                     {
                       org.apache.thrift.protocol.TSet _set244 = iprot.readSetBegin();
-                      _val242 = new HashSet<String>(2*_set244.size);
-                      String _elem245;
+                      _val242 = new java.util.HashSet<java.lang.String>(2*_set244.size);
+                      java.lang.String _elem245;
                       for (int _i246 = 0; _i246 < _set244.size; ++_i246)
                       {
                         _elem245 = iprot.readString();
@@ -36485,12 +37155,12 @@
           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<String>> _iter247 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.util.Set<java.lang.String>> _iter247 : struct.success.entrySet())
             {
               oprot.writeString(_iter247.getKey());
               {
                 oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, _iter247.getValue().size()));
-                for (String _iter248 : _iter247.getValue())
+                for (java.lang.String _iter248 : _iter247.getValue())
                 {
                   oprot.writeString(_iter248);
                 }
@@ -36522,18 +37192,18 @@
 
     }
 
-    private static class getLocalityGroups_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getLocalityGroups_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getLocalityGroups_resultTupleScheme getScheme() {
         return new getLocalityGroups_resultTupleScheme();
       }
     }
 
-    private static class getLocalityGroups_resultTupleScheme extends TupleScheme<getLocalityGroups_result> {
+    private static class getLocalityGroups_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getLocalityGroups_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getLocalityGroups_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -36550,12 +37220,12 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, Set<String>> _iter249 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.util.Set<java.lang.String>> _iter249 : struct.success.entrySet())
             {
               oprot.writeString(_iter249.getKey());
               {
                 oprot.writeI32(_iter249.getValue().size());
-                for (String _iter250 : _iter249.getValue())
+                for (java.lang.String _iter250 : _iter249.getValue())
                 {
                   oprot.writeString(_iter250);
                 }
@@ -36576,21 +37246,21 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getLocalityGroups_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           {
             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);
-            String _key252;
-            Set<String> _val253;
+            struct.success = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>(2*_map251.size);
+            java.lang.String _key252;
+            java.util.Set<java.lang.String> _val253;
             for (int _i254 = 0; _i254 < _map251.size; ++_i254)
             {
               _key252 = iprot.readString();
               {
                 org.apache.thrift.protocol.TSet _set255 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
-                _val253 = new HashSet<String>(2*_set255.size);
-                String _elem256;
+                _val253 = new java.util.HashSet<java.lang.String>(2*_set255.size);
+                java.lang.String _elem256;
                 for (int _i257 = 0; _i257 < _set255.size; ++_i257)
                 {
                   _elem256 = iprot.readString();
@@ -36620,6 +37290,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getIteratorSetting_args implements org.apache.thrift.TBase<getIteratorSetting_args, getIteratorSetting_args._Fields>, java.io.Serializable, Cloneable, Comparable<getIteratorSetting_args>   {
@@ -36630,15 +37303,12 @@
     private static final org.apache.thrift.protocol.TField ITERATOR_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("iteratorName", 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 getIteratorSetting_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getIteratorSetting_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getIteratorSetting_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getIteratorSetting_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public String iteratorName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.lang.String iteratorName; // required
     /**
      * 
      * @see IteratorScope
@@ -36656,10 +37326,10 @@
        */
       SCOPE((short)4, "scope");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -36688,21 +37358,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -36711,15 +37381,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -36728,7 +37398,7 @@
           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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getIteratorSetting_args.class, metaDataMap);
     }
 
@@ -36736,9 +37406,9 @@
     }
 
     public getIteratorSetting_args(
-      ByteBuffer login,
-      String tableName,
-      String iteratorName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.lang.String iteratorName,
       IteratorScope scope)
     {
       this();
@@ -36783,16 +37453,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getIteratorSetting_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getIteratorSetting_args setLogin(ByteBuffer login) {
+    public getIteratorSetting_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -36812,11 +37482,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public getIteratorSetting_args setTableName(String tableName) {
+    public getIteratorSetting_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -36836,11 +37506,11 @@
       }
     }
 
-    public String getIteratorName() {
+    public java.lang.String getIteratorName() {
       return this.iteratorName;
     }
 
-    public getIteratorSetting_args setIteratorName(String iteratorName) {
+    public getIteratorSetting_args setIteratorName(java.lang.String iteratorName) {
       this.iteratorName = iteratorName;
       return this;
     }
@@ -36892,13 +37562,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -36906,7 +37580,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -36914,7 +37588,7 @@
         if (value == null) {
           unsetIteratorName();
         } else {
-          setIteratorName((String)value);
+          setIteratorName((java.lang.String)value);
         }
         break;
 
@@ -36929,7 +37603,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -36944,13 +37618,13 @@
         return getScope();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -36963,11 +37637,11 @@
       case SCOPE:
         return isSetScope();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getIteratorSetting_args)
@@ -36978,6 +37652,8 @@
     public boolean equals(getIteratorSetting_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -37020,29 +37696,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_iteratorName = true && (isSetIteratorName());
-      list.add(present_iteratorName);
-      if (present_iteratorName)
-        list.add(iteratorName);
+      hashCode = hashCode * 8191 + ((isSetIteratorName()) ? 131071 : 524287);
+      if (isSetIteratorName())
+        hashCode = hashCode * 8191 + iteratorName.hashCode();
 
-      boolean present_scope = true && (isSetScope());
-      list.add(present_scope);
-      if (present_scope)
-        list.add(scope.getValue());
+      hashCode = hashCode * 8191 + ((isSetScope()) ? 131071 : 524287);
+      if (isSetScope())
+        hashCode = hashCode * 8191 + scope.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -37053,7 +37725,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -37063,7 +37735,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -37073,7 +37745,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetIteratorName()).compareTo(other.isSetIteratorName());
+      lastComparison = java.lang.Boolean.valueOf(isSetIteratorName()).compareTo(other.isSetIteratorName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -37083,7 +37755,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetScope()).compareTo(other.isSetScope());
+      lastComparison = java.lang.Boolean.valueOf(isSetScope()).compareTo(other.isSetScope());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -37101,16 +37773,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getIteratorSetting_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getIteratorSetting_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -37161,7 +37833,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -37169,13 +37841,13 @@
       }
     }
 
-    private static class getIteratorSetting_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getIteratorSetting_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getIteratorSetting_argsStandardScheme getScheme() {
         return new getIteratorSetting_argsStandardScheme();
       }
     }
 
-    private static class getIteratorSetting_argsStandardScheme extends StandardScheme<getIteratorSetting_args> {
+    private static class getIteratorSetting_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getIteratorSetting_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getIteratorSetting_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -37260,18 +37932,18 @@
 
     }
 
-    private static class getIteratorSetting_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getIteratorSetting_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getIteratorSetting_argsTupleScheme getScheme() {
         return new getIteratorSetting_argsTupleScheme();
       }
     }
 
-    private static class getIteratorSetting_argsTupleScheme extends TupleScheme<getIteratorSetting_args> {
+    private static class getIteratorSetting_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getIteratorSetting_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getIteratorSetting_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -37301,8 +37973,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getIteratorSetting_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -37322,6 +37994,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getIteratorSetting_result implements org.apache.thrift.TBase<getIteratorSetting_result, getIteratorSetting_result._Fields>, java.io.Serializable, Cloneable, Comparable<getIteratorSetting_result>   {
@@ -37332,11 +38007,8 @@
     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 getIteratorSetting_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getIteratorSetting_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getIteratorSetting_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getIteratorSetting_resultTupleSchemeFactory();
 
     public IteratorSetting success; // required
     public AccumuloException ouch1; // required
@@ -37350,10 +38022,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -37382,21 +38054,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -37405,24 +38077,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getIteratorSetting_result.class, metaDataMap);
     }
 
@@ -37568,7 +38240,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
@@ -37605,7 +38277,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -37620,13 +38292,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -37639,11 +38311,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getIteratorSetting_result)
@@ -37654,6 +38326,8 @@
     public boolean equals(getIteratorSetting_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -37696,29 +38370,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -37729,7 +38399,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -37739,7 +38409,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -37749,7 +38419,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -37759,7 +38429,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -37777,16 +38447,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getIteratorSetting_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getIteratorSetting_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -37840,7 +38510,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -37848,13 +38518,13 @@
       }
     }
 
-    private static class getIteratorSetting_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getIteratorSetting_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getIteratorSetting_resultStandardScheme getScheme() {
         return new getIteratorSetting_resultStandardScheme();
       }
     }
 
-    private static class getIteratorSetting_resultStandardScheme extends StandardScheme<getIteratorSetting_result> {
+    private static class getIteratorSetting_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getIteratorSetting_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getIteratorSetting_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -37943,18 +38613,18 @@
 
     }
 
-    private static class getIteratorSetting_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getIteratorSetting_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getIteratorSetting_resultTupleScheme getScheme() {
         return new getIteratorSetting_resultTupleScheme();
       }
     }
 
-    private static class getIteratorSetting_resultTupleScheme extends TupleScheme<getIteratorSetting_result> {
+    private static class getIteratorSetting_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getIteratorSetting_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getIteratorSetting_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -37984,8 +38654,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getIteratorSetting_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = new IteratorSetting();
           struct.success.read(iprot);
@@ -38009,6 +38679,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getMaxRow_args implements org.apache.thrift.TBase<getMaxRow_args, getMaxRow_args._Fields>, java.io.Serializable, Cloneable, Comparable<getMaxRow_args>   {
@@ -38022,18 +38695,15 @@
     private static final org.apache.thrift.protocol.TField END_ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("endRow", org.apache.thrift.protocol.TType.STRING, (short)6);
     private static final org.apache.thrift.protocol.TField END_INCLUSIVE_FIELD_DESC = new org.apache.thrift.protocol.TField("endInclusive", org.apache.thrift.protocol.TType.BOOL, (short)7);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new getMaxRow_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getMaxRow_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getMaxRow_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getMaxRow_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public Set<ByteBuffer> auths; // required
-    public ByteBuffer startRow; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.util.Set<java.nio.ByteBuffer> auths; // required
+    public java.nio.ByteBuffer startRow; // required
     public boolean startInclusive; // required
-    public ByteBuffer endRow; // required
+    public java.nio.ByteBuffer endRow; // required
     public boolean endInclusive; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -38046,10 +38716,10 @@
       END_ROW((short)6, "endRow"),
       END_INCLUSIVE((short)7, "endInclusive");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -38084,21 +38754,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -38107,7 +38777,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -38116,9 +38786,9 @@
     private static final int __STARTINCLUSIVE_ISSET_ID = 0;
     private static final int __ENDINCLUSIVE_ISSET_ID = 1;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -38134,7 +38804,7 @@
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
       tmpMap.put(_Fields.END_INCLUSIVE, new org.apache.thrift.meta_data.FieldMetaData("endInclusive", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getMaxRow_args.class, metaDataMap);
     }
 
@@ -38142,12 +38812,12 @@
     }
 
     public getMaxRow_args(
-      ByteBuffer login,
-      String tableName,
-      Set<ByteBuffer> auths,
-      ByteBuffer startRow,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.util.Set<java.nio.ByteBuffer> auths,
+      java.nio.ByteBuffer startRow,
       boolean startInclusive,
-      ByteBuffer endRow,
+      java.nio.ByteBuffer endRow,
       boolean endInclusive)
     {
       this();
@@ -38174,7 +38844,7 @@
         this.tableName = other.tableName;
       }
       if (other.isSetAuths()) {
-        Set<ByteBuffer> __this__auths = new HashSet<ByteBuffer>(other.auths);
+        java.util.Set<java.nio.ByteBuffer> __this__auths = new java.util.HashSet<java.nio.ByteBuffer>(other.auths);
         this.auths = __this__auths;
       }
       if (other.isSetStartRow()) {
@@ -38209,16 +38879,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getMaxRow_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getMaxRow_args setLogin(ByteBuffer login) {
+    public getMaxRow_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -38238,11 +38908,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public getMaxRow_args setTableName(String tableName) {
+    public getMaxRow_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -38266,22 +38936,22 @@
       return (this.auths == null) ? 0 : this.auths.size();
     }
 
-    public java.util.Iterator<ByteBuffer> getAuthsIterator() {
+    public java.util.Iterator<java.nio.ByteBuffer> getAuthsIterator() {
       return (this.auths == null) ? null : this.auths.iterator();
     }
 
-    public void addToAuths(ByteBuffer elem) {
+    public void addToAuths(java.nio.ByteBuffer elem) {
       if (this.auths == null) {
-        this.auths = new HashSet<ByteBuffer>();
+        this.auths = new java.util.HashSet<java.nio.ByteBuffer>();
       }
       this.auths.add(elem);
     }
 
-    public Set<ByteBuffer> getAuths() {
+    public java.util.Set<java.nio.ByteBuffer> getAuths() {
       return this.auths;
     }
 
-    public getMaxRow_args setAuths(Set<ByteBuffer> auths) {
+    public getMaxRow_args setAuths(java.util.Set<java.nio.ByteBuffer> auths) {
       this.auths = auths;
       return this;
     }
@@ -38306,16 +38976,16 @@
       return startRow == null ? null : startRow.array();
     }
 
-    public ByteBuffer bufferForStartRow() {
+    public java.nio.ByteBuffer bufferForStartRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(startRow);
     }
 
     public getMaxRow_args setStartRow(byte[] startRow) {
-      this.startRow = startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(startRow, startRow.length));
+      this.startRow = startRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(startRow.clone());
       return this;
     }
 
-    public getMaxRow_args setStartRow(ByteBuffer startRow) {
+    public getMaxRow_args setStartRow(java.nio.ByteBuffer startRow) {
       this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       return this;
     }
@@ -38346,16 +39016,16 @@
     }
 
     public void unsetStartInclusive() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID);
     }
 
     /** Returns true if field startInclusive is set (has been assigned a value) and false otherwise */
     public boolean isSetStartInclusive() {
-      return EncodingUtils.testBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID);
     }
 
     public void setStartInclusiveIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID, value);
     }
 
     public byte[] getEndRow() {
@@ -38363,16 +39033,16 @@
       return endRow == null ? null : endRow.array();
     }
 
-    public ByteBuffer bufferForEndRow() {
+    public java.nio.ByteBuffer bufferForEndRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     public getMaxRow_args setEndRow(byte[] endRow) {
-      this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
+      this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
       return this;
     }
 
-    public getMaxRow_args setEndRow(ByteBuffer endRow) {
+    public getMaxRow_args setEndRow(java.nio.ByteBuffer endRow) {
       this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       return this;
     }
@@ -38403,25 +39073,29 @@
     }
 
     public void unsetEndInclusive() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ENDINCLUSIVE_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __ENDINCLUSIVE_ISSET_ID);
     }
 
     /** Returns true if field endInclusive is set (has been assigned a value) and false otherwise */
     public boolean isSetEndInclusive() {
-      return EncodingUtils.testBit(__isset_bitfield, __ENDINCLUSIVE_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __ENDINCLUSIVE_ISSET_ID);
     }
 
     public void setEndInclusiveIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ENDINCLUSIVE_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __ENDINCLUSIVE_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -38429,7 +39103,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -38437,7 +39111,7 @@
         if (value == null) {
           unsetAuths();
         } else {
-          setAuths((Set<ByteBuffer>)value);
+          setAuths((java.util.Set<java.nio.ByteBuffer>)value);
         }
         break;
 
@@ -38445,7 +39119,11 @@
         if (value == null) {
           unsetStartRow();
         } else {
-          setStartRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setStartRow((byte[])value);
+          } else {
+            setStartRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -38453,7 +39131,7 @@
         if (value == null) {
           unsetStartInclusive();
         } else {
-          setStartInclusive((Boolean)value);
+          setStartInclusive((java.lang.Boolean)value);
         }
         break;
 
@@ -38461,7 +39139,11 @@
         if (value == null) {
           unsetEndRow();
         } else {
-          setEndRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setEndRow((byte[])value);
+          } else {
+            setEndRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -38469,14 +39151,14 @@
         if (value == null) {
           unsetEndInclusive();
         } else {
-          setEndInclusive((Boolean)value);
+          setEndInclusive((java.lang.Boolean)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -38500,13 +39182,13 @@
         return isEndInclusive();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -38525,11 +39207,11 @@
       case END_INCLUSIVE:
         return isSetEndInclusive();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getMaxRow_args)
@@ -38540,6 +39222,8 @@
     public boolean equals(getMaxRow_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -38609,44 +39293,33 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_auths = true && (isSetAuths());
-      list.add(present_auths);
-      if (present_auths)
-        list.add(auths);
+      hashCode = hashCode * 8191 + ((isSetAuths()) ? 131071 : 524287);
+      if (isSetAuths())
+        hashCode = hashCode * 8191 + auths.hashCode();
 
-      boolean present_startRow = true && (isSetStartRow());
-      list.add(present_startRow);
-      if (present_startRow)
-        list.add(startRow);
+      hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
+      if (isSetStartRow())
+        hashCode = hashCode * 8191 + startRow.hashCode();
 
-      boolean present_startInclusive = true;
-      list.add(present_startInclusive);
-      if (present_startInclusive)
-        list.add(startInclusive);
+      hashCode = hashCode * 8191 + ((startInclusive) ? 131071 : 524287);
 
-      boolean present_endRow = true && (isSetEndRow());
-      list.add(present_endRow);
-      if (present_endRow)
-        list.add(endRow);
+      hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
+      if (isSetEndRow())
+        hashCode = hashCode * 8191 + endRow.hashCode();
 
-      boolean present_endInclusive = true;
-      list.add(present_endInclusive);
-      if (present_endInclusive)
-        list.add(endInclusive);
+      hashCode = hashCode * 8191 + ((endInclusive) ? 131071 : 524287);
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -38657,7 +39330,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -38667,7 +39340,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -38677,7 +39350,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetAuths()).compareTo(other.isSetAuths());
+      lastComparison = java.lang.Boolean.valueOf(isSetAuths()).compareTo(other.isSetAuths());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -38687,7 +39360,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -38697,7 +39370,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetStartInclusive()).compareTo(other.isSetStartInclusive());
+      lastComparison = java.lang.Boolean.valueOf(isSetStartInclusive()).compareTo(other.isSetStartInclusive());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -38707,7 +39380,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -38717,7 +39390,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetEndInclusive()).compareTo(other.isSetEndInclusive());
+      lastComparison = java.lang.Boolean.valueOf(isSetEndInclusive()).compareTo(other.isSetEndInclusive());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -38735,16 +39408,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getMaxRow_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getMaxRow_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -38811,7 +39484,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -38821,13 +39494,13 @@
       }
     }
 
-    private static class getMaxRow_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getMaxRow_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getMaxRow_argsStandardScheme getScheme() {
         return new getMaxRow_argsStandardScheme();
       }
     }
 
-    private static class getMaxRow_argsStandardScheme extends StandardScheme<getMaxRow_args> {
+    private static class getMaxRow_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getMaxRow_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getMaxRow_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -38859,8 +39532,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set258 = iprot.readSetBegin();
-                  struct.auths = new HashSet<ByteBuffer>(2*_set258.size);
-                  ByteBuffer _elem259;
+                  struct.auths = new java.util.HashSet<java.nio.ByteBuffer>(2*_set258.size);
+                  java.nio.ByteBuffer _elem259;
                   for (int _i260 = 0; _i260 < _set258.size; ++_i260)
                   {
                     _elem259 = iprot.readBinary();
@@ -38934,7 +39607,7 @@
           oprot.writeFieldBegin(AUTHS_FIELD_DESC);
           {
             oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.auths.size()));
-            for (ByteBuffer _iter261 : struct.auths)
+            for (java.nio.ByteBuffer _iter261 : struct.auths)
             {
               oprot.writeBinary(_iter261);
             }
@@ -38964,18 +39637,18 @@
 
     }
 
-    private static class getMaxRow_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getMaxRow_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getMaxRow_argsTupleScheme getScheme() {
         return new getMaxRow_argsTupleScheme();
       }
     }
 
-    private static class getMaxRow_argsTupleScheme extends TupleScheme<getMaxRow_args> {
+    private static class getMaxRow_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getMaxRow_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getMaxRow_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -39007,7 +39680,7 @@
         if (struct.isSetAuths()) {
           {
             oprot.writeI32(struct.auths.size());
-            for (ByteBuffer _iter262 : struct.auths)
+            for (java.nio.ByteBuffer _iter262 : struct.auths)
             {
               oprot.writeBinary(_iter262);
             }
@@ -39029,8 +39702,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getMaxRow_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(7);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(7);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -39042,8 +39715,8 @@
         if (incoming.get(2)) {
           {
             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);
-            ByteBuffer _elem264;
+            struct.auths = new java.util.HashSet<java.nio.ByteBuffer>(2*_set263.size);
+            java.nio.ByteBuffer _elem264;
             for (int _i265 = 0; _i265 < _set263.size; ++_i265)
             {
               _elem264 = iprot.readBinary();
@@ -39071,6 +39744,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getMaxRow_result implements org.apache.thrift.TBase<getMaxRow_result, getMaxRow_result._Fields>, java.io.Serializable, Cloneable, Comparable<getMaxRow_result>   {
@@ -39081,13 +39757,10 @@
     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 getMaxRow_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getMaxRow_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getMaxRow_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getMaxRow_resultTupleSchemeFactory();
 
-    public ByteBuffer success; // required
+    public java.nio.ByteBuffer success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -39099,10 +39772,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -39131,21 +39804,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -39154,24 +39827,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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          , true)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getMaxRow_result.class, metaDataMap);
     }
 
@@ -39179,7 +39852,7 @@
     }
 
     public getMaxRow_result(
-      ByteBuffer success,
+      java.nio.ByteBuffer success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -39226,16 +39899,16 @@
       return success == null ? null : success.array();
     }
 
-    public ByteBuffer bufferForSuccess() {
+    public java.nio.ByteBuffer bufferForSuccess() {
       return org.apache.thrift.TBaseHelper.copyBinary(success);
     }
 
     public getMaxRow_result setSuccess(byte[] success) {
-      this.success = success == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(success, success.length));
+      this.success = success == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(success.clone());
       return this;
     }
 
-    public getMaxRow_result setSuccess(ByteBuffer success) {
+    public getMaxRow_result setSuccess(java.nio.ByteBuffer success) {
       this.success = org.apache.thrift.TBaseHelper.copyBinary(success);
       return this;
     }
@@ -39327,13 +40000,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setSuccess((byte[])value);
+          } else {
+            setSuccess((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -39364,7 +40041,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -39379,13 +40056,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -39398,11 +40075,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getMaxRow_result)
@@ -39413,6 +40090,8 @@
     public boolean equals(getMaxRow_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -39455,29 +40134,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -39488,7 +40163,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -39498,7 +40173,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -39508,7 +40183,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -39518,7 +40193,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -39536,16 +40211,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getMaxRow_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getMaxRow_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -39596,7 +40271,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -39604,13 +40279,13 @@
       }
     }
 
-    private static class getMaxRow_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getMaxRow_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getMaxRow_resultStandardScheme getScheme() {
         return new getMaxRow_resultStandardScheme();
       }
     }
 
-    private static class getMaxRow_resultStandardScheme extends StandardScheme<getMaxRow_result> {
+    private static class getMaxRow_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getMaxRow_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getMaxRow_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -39698,18 +40373,18 @@
 
     }
 
-    private static class getMaxRow_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getMaxRow_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getMaxRow_resultTupleScheme getScheme() {
         return new getMaxRow_resultTupleScheme();
       }
     }
 
-    private static class getMaxRow_resultTupleScheme extends TupleScheme<getMaxRow_result> {
+    private static class getMaxRow_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getMaxRow_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getMaxRow_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -39739,8 +40414,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getMaxRow_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = iprot.readBinary();
           struct.setSuccessIsSet(true);
@@ -39763,6 +40438,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getTableProperties_args implements org.apache.thrift.TBase<getTableProperties_args, getTableProperties_args._Fields>, java.io.Serializable, Cloneable, Comparable<getTableProperties_args>   {
@@ -39771,24 +40449,21 @@
     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 TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", 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 getTableProperties_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getTableProperties_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getTableProperties_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getTableProperties_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // 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"),
       TABLE_NAME((short)2, "tableName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -39813,21 +40488,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -39836,20 +40511,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getTableProperties_args.class, metaDataMap);
     }
 
@@ -39857,8 +40532,8 @@
     }
 
     public getTableProperties_args(
-      ByteBuffer login,
-      String tableName)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -39892,16 +40567,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getTableProperties_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getTableProperties_args setLogin(ByteBuffer login) {
+    public getTableProperties_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -39921,11 +40596,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public getTableProperties_args setTableName(String tableName) {
+    public getTableProperties_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -39945,13 +40620,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -39959,14 +40638,14 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -39975,13 +40654,13 @@
         return getTableName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -39990,11 +40669,11 @@
       case TABLE_NAME:
         return isSetTableName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getTableProperties_args)
@@ -40005,6 +40684,8 @@
     public boolean equals(getTableProperties_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -40029,19 +40710,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -40052,7 +40731,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -40062,7 +40741,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -40080,16 +40759,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getTableProperties_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getTableProperties_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -40124,7 +40803,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -40132,13 +40811,13 @@
       }
     }
 
-    private static class getTableProperties_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getTableProperties_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getTableProperties_argsStandardScheme getScheme() {
         return new getTableProperties_argsStandardScheme();
       }
     }
 
-    private static class getTableProperties_argsStandardScheme extends StandardScheme<getTableProperties_args> {
+    private static class getTableProperties_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getTableProperties_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getTableProperties_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -40197,18 +40876,18 @@
 
     }
 
-    private static class getTableProperties_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getTableProperties_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getTableProperties_argsTupleScheme getScheme() {
         return new getTableProperties_argsTupleScheme();
       }
     }
 
-    private static class getTableProperties_argsTupleScheme extends TupleScheme<getTableProperties_args> {
+    private static class getTableProperties_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getTableProperties_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getTableProperties_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -40226,8 +40905,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getTableProperties_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -40239,6 +40918,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getTableProperties_result implements org.apache.thrift.TBase<getTableProperties_result, getTableProperties_result._Fields>, java.io.Serializable, Cloneable, Comparable<getTableProperties_result>   {
@@ -40249,13 +40931,10 @@
     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 getTableProperties_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getTableProperties_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getTableProperties_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getTableProperties_resultTupleSchemeFactory();
 
-    public Map<String,String> success; // required
+    public java.util.Map<java.lang.String,java.lang.String> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -40267,10 +40946,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -40299,21 +40978,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -40322,26 +41001,26 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getTableProperties_result.class, metaDataMap);
     }
 
@@ -40349,7 +41028,7 @@
     }
 
     public getTableProperties_result(
-      Map<String,String> success,
+      java.util.Map<java.lang.String,java.lang.String> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -40366,7 +41045,7 @@
      */
     public getTableProperties_result(getTableProperties_result other) {
       if (other.isSetSuccess()) {
-        Map<String,String> __this__success = new HashMap<String,String>(other.success);
+        java.util.Map<java.lang.String,java.lang.String> __this__success = new java.util.HashMap<java.lang.String,java.lang.String>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -40396,18 +41075,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, String val) {
+    public void putToSuccess(java.lang.String key, java.lang.String val) {
       if (this.success == null) {
-        this.success = new HashMap<String,String>();
+        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,String> getSuccess() {
+    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
       return this.success;
     }
 
-    public getTableProperties_result setSuccess(Map<String,String> success) {
+    public getTableProperties_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
       this.success = success;
       return this;
     }
@@ -40499,13 +41178,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,String>)value);
+          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
         }
         break;
 
@@ -40536,7 +41215,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -40551,13 +41230,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -40570,11 +41249,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getTableProperties_result)
@@ -40585,6 +41264,8 @@
     public boolean equals(getTableProperties_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -40627,29 +41308,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -40660,7 +41337,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -40670,7 +41347,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -40680,7 +41357,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -40690,7 +41367,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -40708,16 +41385,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getTableProperties_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getTableProperties_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -40768,7 +41445,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -40776,13 +41453,13 @@
       }
     }
 
-    private static class getTableProperties_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getTableProperties_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getTableProperties_resultStandardScheme getScheme() {
         return new getTableProperties_resultStandardScheme();
       }
     }
 
-    private static class getTableProperties_resultStandardScheme extends StandardScheme<getTableProperties_result> {
+    private static class getTableProperties_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getTableProperties_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getTableProperties_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -40798,9 +41475,9 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map266 = iprot.readMapBegin();
-                  struct.success = new HashMap<String,String>(2*_map266.size);
-                  String _key267;
-                  String _val268;
+                  struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map266.size);
+                  java.lang.String _key267;
+                  java.lang.String _val268;
                   for (int _i269 = 0; _i269 < _map266.size; ++_i269)
                   {
                     _key267 = iprot.readString();
@@ -40860,7 +41537,7 @@
           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> _iter270 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter270 : struct.success.entrySet())
             {
               oprot.writeString(_iter270.getKey());
               oprot.writeString(_iter270.getValue());
@@ -40890,18 +41567,18 @@
 
     }
 
-    private static class getTableProperties_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getTableProperties_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getTableProperties_resultTupleScheme getScheme() {
         return new getTableProperties_resultTupleScheme();
       }
     }
 
-    private static class getTableProperties_resultTupleScheme extends TupleScheme<getTableProperties_result> {
+    private static class getTableProperties_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getTableProperties_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getTableProperties_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -40918,7 +41595,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, String> _iter271 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter271 : struct.success.entrySet())
             {
               oprot.writeString(_iter271.getKey());
               oprot.writeString(_iter271.getValue());
@@ -40938,14 +41615,14 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getTableProperties_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           {
             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);
-            String _key273;
-            String _val274;
+            struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map272.size);
+            java.lang.String _key273;
+            java.lang.String _val274;
             for (int _i275 = 0; _i275 < _map272.size; ++_i275)
             {
               _key273 = iprot.readString();
@@ -40973,6 +41650,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class importDirectory_args implements org.apache.thrift.TBase<importDirectory_args, importDirectory_args._Fields>, java.io.Serializable, Cloneable, Comparable<importDirectory_args>   {
@@ -40984,16 +41664,13 @@
     private static final org.apache.thrift.protocol.TField FAILURE_DIR_FIELD_DESC = new org.apache.thrift.protocol.TField("failureDir", org.apache.thrift.protocol.TType.STRING, (short)4);
     private static final org.apache.thrift.protocol.TField SET_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("setTime", org.apache.thrift.protocol.TType.BOOL, (short)5);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new importDirectory_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new importDirectory_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new importDirectory_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new importDirectory_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public String importDir; // required
-    public String failureDir; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.lang.String importDir; // required
+    public java.lang.String failureDir; // required
     public boolean setTime; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -41004,10 +41681,10 @@
       FAILURE_DIR((short)4, "failureDir"),
       SET_TIME((short)5, "setTime");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -41038,21 +41715,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -41061,7 +41738,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -41069,9 +41746,9 @@
     // isset id assignments
     private static final int __SETTIME_ISSET_ID = 0;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -41082,7 +41759,7 @@
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.SET_TIME, new org.apache.thrift.meta_data.FieldMetaData("setTime", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(importDirectory_args.class, metaDataMap);
     }
 
@@ -41090,10 +41767,10 @@
     }
 
     public importDirectory_args(
-      ByteBuffer login,
-      String tableName,
-      String importDir,
-      String failureDir,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.lang.String importDir,
+      java.lang.String failureDir,
       boolean setTime)
     {
       this();
@@ -41144,16 +41821,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public importDirectory_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public importDirectory_args setLogin(ByteBuffer login) {
+    public importDirectory_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -41173,11 +41850,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public importDirectory_args setTableName(String tableName) {
+    public importDirectory_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -41197,11 +41874,11 @@
       }
     }
 
-    public String getImportDir() {
+    public java.lang.String getImportDir() {
       return this.importDir;
     }
 
-    public importDirectory_args setImportDir(String importDir) {
+    public importDirectory_args setImportDir(java.lang.String importDir) {
       this.importDir = importDir;
       return this;
     }
@@ -41221,11 +41898,11 @@
       }
     }
 
-    public String getFailureDir() {
+    public java.lang.String getFailureDir() {
       return this.failureDir;
     }
 
-    public importDirectory_args setFailureDir(String failureDir) {
+    public importDirectory_args setFailureDir(java.lang.String failureDir) {
       this.failureDir = failureDir;
       return this;
     }
@@ -41256,25 +41933,29 @@
     }
 
     public void unsetSetTime() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SETTIME_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SETTIME_ISSET_ID);
     }
 
     /** Returns true if field setTime is set (has been assigned a value) and false otherwise */
     public boolean isSetSetTime() {
-      return EncodingUtils.testBit(__isset_bitfield, __SETTIME_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SETTIME_ISSET_ID);
     }
 
     public void setSetTimeIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SETTIME_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SETTIME_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -41282,7 +41963,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -41290,7 +41971,7 @@
         if (value == null) {
           unsetImportDir();
         } else {
-          setImportDir((String)value);
+          setImportDir((java.lang.String)value);
         }
         break;
 
@@ -41298,7 +41979,7 @@
         if (value == null) {
           unsetFailureDir();
         } else {
-          setFailureDir((String)value);
+          setFailureDir((java.lang.String)value);
         }
         break;
 
@@ -41306,14 +41987,14 @@
         if (value == null) {
           unsetSetTime();
         } else {
-          setSetTime((Boolean)value);
+          setSetTime((java.lang.Boolean)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -41331,13 +42012,13 @@
         return isSetTime();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -41352,11 +42033,11 @@
       case SET_TIME:
         return isSetSetTime();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof importDirectory_args)
@@ -41367,6 +42048,8 @@
     public boolean equals(importDirectory_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -41418,34 +42101,27 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_importDir = true && (isSetImportDir());
-      list.add(present_importDir);
-      if (present_importDir)
-        list.add(importDir);
+      hashCode = hashCode * 8191 + ((isSetImportDir()) ? 131071 : 524287);
+      if (isSetImportDir())
+        hashCode = hashCode * 8191 + importDir.hashCode();
 
-      boolean present_failureDir = true && (isSetFailureDir());
-      list.add(present_failureDir);
-      if (present_failureDir)
-        list.add(failureDir);
+      hashCode = hashCode * 8191 + ((isSetFailureDir()) ? 131071 : 524287);
+      if (isSetFailureDir())
+        hashCode = hashCode * 8191 + failureDir.hashCode();
 
-      boolean present_setTime = true;
-      list.add(present_setTime);
-      if (present_setTime)
-        list.add(setTime);
+      hashCode = hashCode * 8191 + ((setTime) ? 131071 : 524287);
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -41456,7 +42132,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -41466,7 +42142,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -41476,7 +42152,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetImportDir()).compareTo(other.isSetImportDir());
+      lastComparison = java.lang.Boolean.valueOf(isSetImportDir()).compareTo(other.isSetImportDir());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -41486,7 +42162,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetFailureDir()).compareTo(other.isSetFailureDir());
+      lastComparison = java.lang.Boolean.valueOf(isSetFailureDir()).compareTo(other.isSetFailureDir());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -41496,7 +42172,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetSetTime()).compareTo(other.isSetSetTime());
+      lastComparison = java.lang.Boolean.valueOf(isSetSetTime()).compareTo(other.isSetSetTime());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -41514,16 +42190,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("importDirectory_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("importDirectory_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -41578,7 +42254,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -41588,13 +42264,13 @@
       }
     }
 
-    private static class importDirectory_argsStandardSchemeFactory implements SchemeFactory {
+    private static class importDirectory_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public importDirectory_argsStandardScheme getScheme() {
         return new importDirectory_argsStandardScheme();
       }
     }
 
-    private static class importDirectory_argsStandardScheme extends StandardScheme<importDirectory_args> {
+    private static class importDirectory_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<importDirectory_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, importDirectory_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -41690,18 +42366,18 @@
 
     }
 
-    private static class importDirectory_argsTupleSchemeFactory implements SchemeFactory {
+    private static class importDirectory_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public importDirectory_argsTupleScheme getScheme() {
         return new importDirectory_argsTupleScheme();
       }
     }
 
-    private static class importDirectory_argsTupleScheme extends TupleScheme<importDirectory_args> {
+    private static class importDirectory_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<importDirectory_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, importDirectory_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -41737,8 +42413,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, importDirectory_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(5);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(5);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -41762,6 +42438,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class importDirectory_result implements org.apache.thrift.TBase<importDirectory_result, importDirectory_result._Fields>, java.io.Serializable, Cloneable, Comparable<importDirectory_result>   {
@@ -41771,11 +42450,8 @@
     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)2);
     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)3);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new importDirectory_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new importDirectory_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new importDirectory_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new importDirectory_resultTupleSchemeFactory();
 
     public TableNotFoundException ouch1; // required
     public AccumuloException ouch3; // required
@@ -41787,10 +42463,10 @@
       OUCH3((short)2, "ouch3"),
       OUCH4((short)3, "ouch4");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -41817,21 +42493,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -41840,22 +42516,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(importDirectory_result.class, metaDataMap);
     }
 
@@ -41971,7 +42647,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -42000,7 +42676,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -42012,13 +42688,13 @@
         return getOuch4();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -42029,11 +42705,11 @@
       case OUCH4:
         return isSetOuch4();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof importDirectory_result)
@@ -42044,6 +42720,8 @@
     public boolean equals(importDirectory_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -42077,24 +42755,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      boolean present_ouch4 = true && (isSetOuch4());
-      list.add(present_ouch4);
-      if (present_ouch4)
-        list.add(ouch4);
+      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
+      if (isSetOuch4())
+        hashCode = hashCode * 8191 + ouch4.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -42105,7 +42780,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -42115,7 +42790,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -42125,7 +42800,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -42143,16 +42818,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("importDirectory_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("importDirectory_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -42195,7 +42870,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -42203,13 +42878,13 @@
       }
     }
 
-    private static class importDirectory_resultStandardSchemeFactory implements SchemeFactory {
+    private static class importDirectory_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public importDirectory_resultStandardScheme getScheme() {
         return new importDirectory_resultStandardScheme();
       }
     }
 
-    private static class importDirectory_resultStandardScheme extends StandardScheme<importDirectory_result> {
+    private static class importDirectory_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<importDirectory_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, importDirectory_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -42284,18 +42959,18 @@
 
     }
 
-    private static class importDirectory_resultTupleSchemeFactory implements SchemeFactory {
+    private static class importDirectory_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public importDirectory_resultTupleScheme getScheme() {
         return new importDirectory_resultTupleScheme();
       }
     }
 
-    private static class importDirectory_resultTupleScheme extends TupleScheme<importDirectory_result> {
+    private static class importDirectory_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<importDirectory_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, importDirectory_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -42319,8 +42994,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, importDirectory_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new TableNotFoundException();
           struct.ouch1.read(iprot);
@@ -42339,6 +43014,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class importTable_args implements org.apache.thrift.TBase<importTable_args, importTable_args._Fields>, java.io.Serializable, Cloneable, Comparable<importTable_args>   {
@@ -42348,15 +43026,12 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField IMPORT_DIR_FIELD_DESC = new org.apache.thrift.protocol.TField("importDir", 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 importTable_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new importTable_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new importTable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new importTable_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public String importDir; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.lang.String importDir; // 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 {
@@ -42364,10 +43039,10 @@
       TABLE_NAME((short)2, "tableName"),
       IMPORT_DIR((short)3, "importDir");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -42394,21 +43069,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -42417,22 +43092,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.IMPORT_DIR, new org.apache.thrift.meta_data.FieldMetaData("importDir", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(importTable_args.class, metaDataMap);
     }
 
@@ -42440,9 +43115,9 @@
     }
 
     public importTable_args(
-      ByteBuffer login,
-      String tableName,
-      String importDir)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.lang.String importDir)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -42481,16 +43156,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public importTable_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public importTable_args setLogin(ByteBuffer login) {
+    public importTable_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -42510,11 +43185,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public importTable_args setTableName(String tableName) {
+    public importTable_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -42534,11 +43209,11 @@
       }
     }
 
-    public String getImportDir() {
+    public java.lang.String getImportDir() {
       return this.importDir;
     }
 
-    public importTable_args setImportDir(String importDir) {
+    public importTable_args setImportDir(java.lang.String importDir) {
       this.importDir = importDir;
       return this;
     }
@@ -42558,13 +43233,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -42572,7 +43251,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -42580,14 +43259,14 @@
         if (value == null) {
           unsetImportDir();
         } else {
-          setImportDir((String)value);
+          setImportDir((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -42599,13 +43278,13 @@
         return getImportDir();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -42616,11 +43295,11 @@
       case IMPORT_DIR:
         return isSetImportDir();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof importTable_args)
@@ -42631,6 +43310,8 @@
     public boolean equals(importTable_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -42664,24 +43345,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_importDir = true && (isSetImportDir());
-      list.add(present_importDir);
-      if (present_importDir)
-        list.add(importDir);
+      hashCode = hashCode * 8191 + ((isSetImportDir()) ? 131071 : 524287);
+      if (isSetImportDir())
+        hashCode = hashCode * 8191 + importDir.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -42692,7 +43370,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -42702,7 +43380,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -42712,7 +43390,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetImportDir()).compareTo(other.isSetImportDir());
+      lastComparison = java.lang.Boolean.valueOf(isSetImportDir()).compareTo(other.isSetImportDir());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -42730,16 +43408,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("importTable_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("importTable_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -42782,7 +43460,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -42790,13 +43468,13 @@
       }
     }
 
-    private static class importTable_argsStandardSchemeFactory implements SchemeFactory {
+    private static class importTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public importTable_argsStandardScheme getScheme() {
         return new importTable_argsStandardScheme();
       }
     }
 
-    private static class importTable_argsStandardScheme extends StandardScheme<importTable_args> {
+    private static class importTable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<importTable_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, importTable_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -42868,18 +43546,18 @@
 
     }
 
-    private static class importTable_argsTupleSchemeFactory implements SchemeFactory {
+    private static class importTable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public importTable_argsTupleScheme getScheme() {
         return new importTable_argsTupleScheme();
       }
     }
 
-    private static class importTable_argsTupleScheme extends TupleScheme<importTable_args> {
+    private static class importTable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<importTable_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, importTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -42903,8 +43581,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, importTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -42920,6 +43598,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class importTable_result implements org.apache.thrift.TBase<importTable_result, importTable_result._Fields>, java.io.Serializable, Cloneable, Comparable<importTable_result>   {
@@ -42929,11 +43610,8 @@
     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 importTable_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new importTable_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new importTable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new importTable_resultTupleSchemeFactory();
 
     public TableExistsException ouch1; // required
     public AccumuloException ouch2; // required
@@ -42945,10 +43623,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -42975,21 +43653,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -42998,22 +43676,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableExistsException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(importTable_result.class, metaDataMap);
     }
 
@@ -43129,7 +43807,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -43158,7 +43836,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -43170,13 +43848,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -43187,11 +43865,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof importTable_result)
@@ -43202,6 +43880,8 @@
     public boolean equals(importTable_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -43235,24 +43915,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -43263,7 +43940,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -43273,7 +43950,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -43283,7 +43960,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -43301,16 +43978,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("importTable_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("importTable_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -43353,7 +44030,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -43361,13 +44038,13 @@
       }
     }
 
-    private static class importTable_resultStandardSchemeFactory implements SchemeFactory {
+    private static class importTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public importTable_resultStandardScheme getScheme() {
         return new importTable_resultStandardScheme();
       }
     }
 
-    private static class importTable_resultStandardScheme extends StandardScheme<importTable_result> {
+    private static class importTable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<importTable_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, importTable_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -43442,18 +44119,18 @@
 
     }
 
-    private static class importTable_resultTupleSchemeFactory implements SchemeFactory {
+    private static class importTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public importTable_resultTupleScheme getScheme() {
         return new importTable_resultTupleScheme();
       }
     }
 
-    private static class importTable_resultTupleScheme extends TupleScheme<importTable_result> {
+    private static class importTable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<importTable_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, importTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -43477,8 +44154,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, importTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new TableExistsException();
           struct.ouch1.read(iprot);
@@ -43497,6 +44174,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listSplits_args implements org.apache.thrift.TBase<listSplits_args, listSplits_args._Fields>, java.io.Serializable, Cloneable, Comparable<listSplits_args>   {
@@ -43506,14 +44186,11 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField MAX_SPLITS_FIELD_DESC = new org.apache.thrift.protocol.TField("maxSplits", 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 listSplits_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new listSplits_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listSplits_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listSplits_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public int maxSplits; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -43522,10 +44199,10 @@
       TABLE_NAME((short)2, "tableName"),
       MAX_SPLITS((short)3, "maxSplits");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -43552,21 +44229,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -43575,7 +44252,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -43583,16 +44260,16 @@
     // isset id assignments
     private static final int __MAXSPLITS_ISSET_ID = 0;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.MAX_SPLITS, new org.apache.thrift.meta_data.FieldMetaData("maxSplits", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listSplits_args.class, metaDataMap);
     }
 
@@ -43600,8 +44277,8 @@
     }
 
     public listSplits_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       int maxSplits)
     {
       this();
@@ -43642,16 +44319,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public listSplits_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public listSplits_args setLogin(ByteBuffer login) {
+    public listSplits_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -43671,11 +44348,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public listSplits_args setTableName(String tableName) {
+    public listSplits_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -43706,25 +44383,29 @@
     }
 
     public void unsetMaxSplits() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __MAXSPLITS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __MAXSPLITS_ISSET_ID);
     }
 
     /** Returns true if field maxSplits is set (has been assigned a value) and false otherwise */
     public boolean isSetMaxSplits() {
-      return EncodingUtils.testBit(__isset_bitfield, __MAXSPLITS_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __MAXSPLITS_ISSET_ID);
     }
 
     public void setMaxSplitsIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __MAXSPLITS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __MAXSPLITS_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -43732,7 +44413,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -43740,14 +44421,14 @@
         if (value == null) {
           unsetMaxSplits();
         } else {
-          setMaxSplits((Integer)value);
+          setMaxSplits((java.lang.Integer)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -43759,13 +44440,13 @@
         return getMaxSplits();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -43776,11 +44457,11 @@
       case MAX_SPLITS:
         return isSetMaxSplits();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listSplits_args)
@@ -43791,6 +44472,8 @@
     public boolean equals(listSplits_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -43824,24 +44507,19 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_maxSplits = true;
-      list.add(present_maxSplits);
-      if (present_maxSplits)
-        list.add(maxSplits);
+      hashCode = hashCode * 8191 + maxSplits;
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -43852,7 +44530,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -43862,7 +44540,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -43872,7 +44550,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetMaxSplits()).compareTo(other.isSetMaxSplits());
+      lastComparison = java.lang.Boolean.valueOf(isSetMaxSplits()).compareTo(other.isSetMaxSplits());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -43890,16 +44568,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listSplits_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listSplits_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -43938,7 +44616,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -43948,13 +44626,13 @@
       }
     }
 
-    private static class listSplits_argsStandardSchemeFactory implements SchemeFactory {
+    private static class listSplits_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listSplits_argsStandardScheme getScheme() {
         return new listSplits_argsStandardScheme();
       }
     }
 
-    private static class listSplits_argsStandardScheme extends StandardScheme<listSplits_args> {
+    private static class listSplits_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<listSplits_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, listSplits_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -44024,18 +44702,18 @@
 
     }
 
-    private static class listSplits_argsTupleSchemeFactory implements SchemeFactory {
+    private static class listSplits_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listSplits_argsTupleScheme getScheme() {
         return new listSplits_argsTupleScheme();
       }
     }
 
-    private static class listSplits_argsTupleScheme extends TupleScheme<listSplits_args> {
+    private static class listSplits_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<listSplits_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, listSplits_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -44059,8 +44737,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, listSplits_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -44076,6 +44754,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listSplits_result implements org.apache.thrift.TBase<listSplits_result, listSplits_result._Fields>, java.io.Serializable, Cloneable, Comparable<listSplits_result>   {
@@ -44086,13 +44767,10 @@
     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 listSplits_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new listSplits_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listSplits_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listSplits_resultTupleSchemeFactory();
 
-    public List<ByteBuffer> success; // required
+    public java.util.List<java.nio.ByteBuffer> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -44104,10 +44782,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -44136,21 +44814,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -44159,25 +44837,25 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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              , true))));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listSplits_result.class, metaDataMap);
     }
 
@@ -44185,7 +44863,7 @@
     }
 
     public listSplits_result(
-      List<ByteBuffer> success,
+      java.util.List<java.nio.ByteBuffer> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -44202,7 +44880,7 @@
      */
     public listSplits_result(listSplits_result other) {
       if (other.isSetSuccess()) {
-        List<ByteBuffer> __this__success = new ArrayList<ByteBuffer>(other.success);
+        java.util.List<java.nio.ByteBuffer> __this__success = new java.util.ArrayList<java.nio.ByteBuffer>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -44232,22 +44910,22 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public java.util.Iterator<ByteBuffer> getSuccessIterator() {
+    public java.util.Iterator<java.nio.ByteBuffer> getSuccessIterator() {
       return (this.success == null) ? null : this.success.iterator();
     }
 
-    public void addToSuccess(ByteBuffer elem) {
+    public void addToSuccess(java.nio.ByteBuffer elem) {
       if (this.success == null) {
-        this.success = new ArrayList<ByteBuffer>();
+        this.success = new java.util.ArrayList<java.nio.ByteBuffer>();
       }
       this.success.add(elem);
     }
 
-    public List<ByteBuffer> getSuccess() {
+    public java.util.List<java.nio.ByteBuffer> getSuccess() {
       return this.success;
     }
 
-    public listSplits_result setSuccess(List<ByteBuffer> success) {
+    public listSplits_result setSuccess(java.util.List<java.nio.ByteBuffer> success) {
       this.success = success;
       return this;
     }
@@ -44339,13 +45017,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((List<ByteBuffer>)value);
+          setSuccess((java.util.List<java.nio.ByteBuffer>)value);
         }
         break;
 
@@ -44376,7 +45054,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -44391,13 +45069,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -44410,11 +45088,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listSplits_result)
@@ -44425,6 +45103,8 @@
     public boolean equals(listSplits_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -44467,29 +45147,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -44500,7 +45176,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -44510,7 +45186,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -44520,7 +45196,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -44530,7 +45206,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -44548,16 +45224,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listSplits_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listSplits_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -44608,7 +45284,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -44616,13 +45292,13 @@
       }
     }
 
-    private static class listSplits_resultStandardSchemeFactory implements SchemeFactory {
+    private static class listSplits_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listSplits_resultStandardScheme getScheme() {
         return new listSplits_resultStandardScheme();
       }
     }
 
-    private static class listSplits_resultStandardScheme extends StandardScheme<listSplits_result> {
+    private static class listSplits_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<listSplits_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, listSplits_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -44638,8 +45314,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                 {
                   org.apache.thrift.protocol.TList _list276 = iprot.readListBegin();
-                  struct.success = new ArrayList<ByteBuffer>(_list276.size);
-                  ByteBuffer _elem277;
+                  struct.success = new java.util.ArrayList<java.nio.ByteBuffer>(_list276.size);
+                  java.nio.ByteBuffer _elem277;
                   for (int _i278 = 0; _i278 < _list276.size; ++_i278)
                   {
                     _elem277 = iprot.readBinary();
@@ -44698,7 +45374,7 @@
           oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
           {
             oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
-            for (ByteBuffer _iter279 : struct.success)
+            for (java.nio.ByteBuffer _iter279 : struct.success)
             {
               oprot.writeBinary(_iter279);
             }
@@ -44727,18 +45403,18 @@
 
     }
 
-    private static class listSplits_resultTupleSchemeFactory implements SchemeFactory {
+    private static class listSplits_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listSplits_resultTupleScheme getScheme() {
         return new listSplits_resultTupleScheme();
       }
     }
 
-    private static class listSplits_resultTupleScheme extends TupleScheme<listSplits_result> {
+    private static class listSplits_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<listSplits_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, listSplits_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -44755,7 +45431,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (ByteBuffer _iter280 : struct.success)
+            for (java.nio.ByteBuffer _iter280 : struct.success)
             {
               oprot.writeBinary(_iter280);
             }
@@ -44774,13 +45450,13 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, listSplits_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           {
             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);
-            ByteBuffer _elem282;
+            struct.success = new java.util.ArrayList<java.nio.ByteBuffer>(_list281.size);
+            java.nio.ByteBuffer _elem282;
             for (int _i283 = 0; _i283 < _list281.size; ++_i283)
             {
               _elem282 = iprot.readBinary();
@@ -44807,6 +45483,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listTables_args implements org.apache.thrift.TBase<listTables_args, listTables_args._Fields>, java.io.Serializable, Cloneable, Comparable<listTables_args>   {
@@ -44814,22 +45493,19 @@
 
     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 listTables_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new listTables_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listTables_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listTables_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
+    public java.nio.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -44852,21 +45528,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -44875,18 +45551,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listTables_args.class, metaDataMap);
     }
 
@@ -44894,7 +45570,7 @@
     }
 
     public listTables_args(
-      ByteBuffer login)
+      java.nio.ByteBuffer login)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -44923,16 +45599,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public listTables_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public listTables_args setLogin(ByteBuffer login) {
+    public listTables_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -44952,43 +45628,47 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case LOGIN:
         return isSetLogin();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listTables_args)
@@ -44999,6 +45679,8 @@
     public boolean equals(listTables_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -45014,14 +45696,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -45032,7 +45713,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -45050,16 +45731,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listTables_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listTables_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -45086,7 +45767,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -45094,13 +45775,13 @@
       }
     }
 
-    private static class listTables_argsStandardSchemeFactory implements SchemeFactory {
+    private static class listTables_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listTables_argsStandardScheme getScheme() {
         return new listTables_argsStandardScheme();
       }
     }
 
-    private static class listTables_argsStandardScheme extends StandardScheme<listTables_args> {
+    private static class listTables_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<listTables_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, listTables_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -45146,18 +45827,18 @@
 
     }
 
-    private static class listTables_argsTupleSchemeFactory implements SchemeFactory {
+    private static class listTables_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listTables_argsTupleScheme getScheme() {
         return new listTables_argsTupleScheme();
       }
     }
 
-    private static class listTables_argsTupleScheme extends TupleScheme<listTables_args> {
+    private static class listTables_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<listTables_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, listTables_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -45169,8 +45850,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, listTables_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -45178,6 +45859,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listTables_result implements org.apache.thrift.TBase<listTables_result, listTables_result._Fields>, java.io.Serializable, Cloneable, Comparable<listTables_result>   {
@@ -45185,22 +45869,19 @@
 
     private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.SET, (short)0);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new listTables_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new listTables_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listTables_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listTables_resultTupleSchemeFactory();
 
-    public Set<String> success; // required
+    public java.util.Set<java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -45223,21 +45904,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -45246,19 +45927,19 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.SetMetaData(org.apache.thrift.protocol.TType.SET, 
               new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listTables_result.class, metaDataMap);
     }
 
@@ -45266,7 +45947,7 @@
     }
 
     public listTables_result(
-      Set<String> success)
+      java.util.Set<java.lang.String> success)
     {
       this();
       this.success = success;
@@ -45277,7 +45958,7 @@
      */
     public listTables_result(listTables_result other) {
       if (other.isSetSuccess()) {
-        Set<String> __this__success = new HashSet<String>(other.success);
+        java.util.Set<java.lang.String> __this__success = new java.util.HashSet<java.lang.String>(other.success);
         this.success = __this__success;
       }
     }
@@ -45295,22 +45976,22 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public java.util.Iterator<String> getSuccessIterator() {
+    public java.util.Iterator<java.lang.String> getSuccessIterator() {
       return (this.success == null) ? null : this.success.iterator();
     }
 
-    public void addToSuccess(String elem) {
+    public void addToSuccess(java.lang.String elem) {
       if (this.success == null) {
-        this.success = new HashSet<String>();
+        this.success = new java.util.HashSet<java.lang.String>();
       }
       this.success.add(elem);
     }
 
-    public Set<String> getSuccess() {
+    public java.util.Set<java.lang.String> getSuccess() {
       return this.success;
     }
 
-    public listTables_result setSuccess(Set<String> success) {
+    public listTables_result setSuccess(java.util.Set<java.lang.String> success) {
       this.success = success;
       return this;
     }
@@ -45330,43 +46011,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Set<String>)value);
+          setSuccess((java.util.Set<java.lang.String>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SUCCESS:
         return isSetSuccess();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listTables_result)
@@ -45377,6 +46058,8 @@
     public boolean equals(listTables_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -45392,14 +46075,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -45410,7 +46092,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -45428,16 +46110,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listTables_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listTables_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -45464,7 +46146,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -45472,13 +46154,13 @@
       }
     }
 
-    private static class listTables_resultStandardSchemeFactory implements SchemeFactory {
+    private static class listTables_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listTables_resultStandardScheme getScheme() {
         return new listTables_resultStandardScheme();
       }
     }
 
-    private static class listTables_resultStandardScheme extends StandardScheme<listTables_result> {
+    private static class listTables_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<listTables_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, listTables_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -45494,8 +46176,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set284 = iprot.readSetBegin();
-                  struct.success = new HashSet<String>(2*_set284.size);
-                  String _elem285;
+                  struct.success = new java.util.HashSet<java.lang.String>(2*_set284.size);
+                  java.lang.String _elem285;
                   for (int _i286 = 0; _i286 < _set284.size; ++_i286)
                   {
                     _elem285 = iprot.readString();
@@ -45527,7 +46209,7 @@
           oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
           {
             oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
-            for (String _iter287 : struct.success)
+            for (java.lang.String _iter287 : struct.success)
             {
               oprot.writeString(_iter287);
             }
@@ -45541,18 +46223,18 @@
 
     }
 
-    private static class listTables_resultTupleSchemeFactory implements SchemeFactory {
+    private static class listTables_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listTables_resultTupleScheme getScheme() {
         return new listTables_resultTupleScheme();
       }
     }
 
-    private static class listTables_resultTupleScheme extends TupleScheme<listTables_result> {
+    private static class listTables_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<listTables_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, listTables_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -45560,7 +46242,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (String _iter288 : struct.success)
+            for (java.lang.String _iter288 : struct.success)
             {
               oprot.writeString(_iter288);
             }
@@ -45570,13 +46252,13 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, listTables_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           {
             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);
-            String _elem290;
+            struct.success = new java.util.HashSet<java.lang.String>(2*_set289.size);
+            java.lang.String _elem290;
             for (int _i291 = 0; _i291 < _set289.size; ++_i291)
             {
               _elem290 = iprot.readString();
@@ -45588,6 +46270,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listIterators_args implements org.apache.thrift.TBase<listIterators_args, listIterators_args._Fields>, java.io.Serializable, Cloneable, Comparable<listIterators_args>   {
@@ -45596,24 +46281,21 @@
     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 TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", 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 listIterators_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new listIterators_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listIterators_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listIterators_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // 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"),
       TABLE_NAME((short)2, "tableName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -45638,21 +46320,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -45661,20 +46343,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listIterators_args.class, metaDataMap);
     }
 
@@ -45682,8 +46364,8 @@
     }
 
     public listIterators_args(
-      ByteBuffer login,
-      String tableName)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -45717,16 +46399,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public listIterators_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public listIterators_args setLogin(ByteBuffer login) {
+    public listIterators_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -45746,11 +46428,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public listIterators_args setTableName(String tableName) {
+    public listIterators_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -45770,13 +46452,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -45784,14 +46470,14 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -45800,13 +46486,13 @@
         return getTableName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -45815,11 +46501,11 @@
       case TABLE_NAME:
         return isSetTableName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listIterators_args)
@@ -45830,6 +46516,8 @@
     public boolean equals(listIterators_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -45854,19 +46542,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -45877,7 +46563,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -45887,7 +46573,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -45905,16 +46591,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listIterators_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listIterators_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -45949,7 +46635,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -45957,13 +46643,13 @@
       }
     }
 
-    private static class listIterators_argsStandardSchemeFactory implements SchemeFactory {
+    private static class listIterators_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listIterators_argsStandardScheme getScheme() {
         return new listIterators_argsStandardScheme();
       }
     }
 
-    private static class listIterators_argsStandardScheme extends StandardScheme<listIterators_args> {
+    private static class listIterators_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<listIterators_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, listIterators_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -46022,18 +46708,18 @@
 
     }
 
-    private static class listIterators_argsTupleSchemeFactory implements SchemeFactory {
+    private static class listIterators_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listIterators_argsTupleScheme getScheme() {
         return new listIterators_argsTupleScheme();
       }
     }
 
-    private static class listIterators_argsTupleScheme extends TupleScheme<listIterators_args> {
+    private static class listIterators_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<listIterators_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, listIterators_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -46051,8 +46737,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, listIterators_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -46064,6 +46750,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listIterators_result implements org.apache.thrift.TBase<listIterators_result, listIterators_result._Fields>, java.io.Serializable, Cloneable, Comparable<listIterators_result>   {
@@ -46074,13 +46763,10 @@
     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 listIterators_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new listIterators_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listIterators_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listIterators_resultTupleSchemeFactory();
 
-    public Map<String,Set<IteratorScope>> success; // required
+    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -46092,10 +46778,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -46124,21 +46810,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -46147,27 +46833,27 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listIterators_result.class, metaDataMap);
     }
 
@@ -46175,7 +46861,7 @@
     }
 
     public listIterators_result(
-      Map<String,Set<IteratorScope>> success,
+      java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -46192,15 +46878,15 @@
      */
     public listIterators_result(listIterators_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()) {
+        java.util.Map<java.lang.String,java.util.Set<IteratorScope>> __this__success = new java.util.HashMap<java.lang.String,java.util.Set<IteratorScope>>(other.success.size());
+        for (java.util.Map.Entry<java.lang.String, java.util.Set<IteratorScope>> other_element : other.success.entrySet()) {
 
-          String other_element_key = other_element.getKey();
-          Set<IteratorScope> other_element_value = other_element.getValue();
+          java.lang.String other_element_key = other_element.getKey();
+          java.util.Set<IteratorScope> other_element_value = other_element.getValue();
 
-          String __this__success_copy_key = other_element_key;
+          java.lang.String __this__success_copy_key = other_element_key;
 
-          Set<IteratorScope> __this__success_copy_value = new HashSet<IteratorScope>(other_element_value.size());
+          java.util.Set<IteratorScope> __this__success_copy_value = new java.util.HashSet<IteratorScope>(other_element_value.size());
           for (IteratorScope other_element_value_element : other_element_value) {
             __this__success_copy_value.add(other_element_value_element);
           }
@@ -46236,18 +46922,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, Set<IteratorScope> val) {
+    public void putToSuccess(java.lang.String key, java.util.Set<IteratorScope> val) {
       if (this.success == null) {
-        this.success = new HashMap<String,Set<IteratorScope>>();
+        this.success = new java.util.HashMap<java.lang.String,java.util.Set<IteratorScope>>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,Set<IteratorScope>> getSuccess() {
+    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> getSuccess() {
       return this.success;
     }
 
-    public listIterators_result setSuccess(Map<String,Set<IteratorScope>> success) {
+    public listIterators_result setSuccess(java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success) {
       this.success = success;
       return this;
     }
@@ -46339,13 +47025,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,Set<IteratorScope>>)value);
+          setSuccess((java.util.Map<java.lang.String,java.util.Set<IteratorScope>>)value);
         }
         break;
 
@@ -46376,7 +47062,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -46391,13 +47077,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -46410,11 +47096,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listIterators_result)
@@ -46425,6 +47111,8 @@
     public boolean equals(listIterators_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -46467,29 +47155,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -46500,7 +47184,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -46510,7 +47194,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -46520,7 +47204,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -46530,7 +47214,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -46548,16 +47232,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listIterators_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listIterators_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -46608,7 +47292,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -46616,13 +47300,13 @@
       }
     }
 
-    private static class listIterators_resultStandardSchemeFactory implements SchemeFactory {
+    private static class listIterators_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listIterators_resultStandardScheme getScheme() {
         return new listIterators_resultStandardScheme();
       }
     }
 
-    private static class listIterators_resultStandardScheme extends StandardScheme<listIterators_result> {
+    private static class listIterators_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<listIterators_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, listIterators_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -46638,15 +47322,15 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map292 = iprot.readMapBegin();
-                  struct.success = new HashMap<String,Set<IteratorScope>>(2*_map292.size);
-                  String _key293;
-                  Set<IteratorScope> _val294;
+                  struct.success = new java.util.HashMap<java.lang.String,java.util.Set<IteratorScope>>(2*_map292.size);
+                  java.lang.String _key293;
+                  java.util.Set<IteratorScope> _val294;
                   for (int _i295 = 0; _i295 < _map292.size; ++_i295)
                   {
                     _key293 = iprot.readString();
                     {
                       org.apache.thrift.protocol.TSet _set296 = iprot.readSetBegin();
-                      _val294 = new HashSet<IteratorScope>(2*_set296.size);
+                      _val294 = new java.util.HashSet<IteratorScope>(2*_set296.size);
                       IteratorScope _elem297;
                       for (int _i298 = 0; _i298 < _set296.size; ++_i298)
                       {
@@ -46710,7 +47394,7 @@
           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>> _iter299 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.util.Set<IteratorScope>> _iter299 : struct.success.entrySet())
             {
               oprot.writeString(_iter299.getKey());
               {
@@ -46747,18 +47431,18 @@
 
     }
 
-    private static class listIterators_resultTupleSchemeFactory implements SchemeFactory {
+    private static class listIterators_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listIterators_resultTupleScheme getScheme() {
         return new listIterators_resultTupleScheme();
       }
     }
 
-    private static class listIterators_resultTupleScheme extends TupleScheme<listIterators_result> {
+    private static class listIterators_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<listIterators_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, listIterators_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -46775,7 +47459,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, Set<IteratorScope>> _iter301 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.util.Set<IteratorScope>> _iter301 : struct.success.entrySet())
             {
               oprot.writeString(_iter301.getKey());
               {
@@ -46801,20 +47485,20 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, listIterators_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           {
             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);
-            String _key304;
-            Set<IteratorScope> _val305;
+            struct.success = new java.util.HashMap<java.lang.String,java.util.Set<IteratorScope>>(2*_map303.size);
+            java.lang.String _key304;
+            java.util.Set<IteratorScope> _val305;
             for (int _i306 = 0; _i306 < _map303.size; ++_i306)
             {
               _key304 = iprot.readString();
               {
                 org.apache.thrift.protocol.TSet _set307 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, iprot.readI32());
-                _val305 = new HashSet<IteratorScope>(2*_set307.size);
+                _val305 = new java.util.HashSet<IteratorScope>(2*_set307.size);
                 IteratorScope _elem308;
                 for (int _i309 = 0; _i309 < _set307.size; ++_i309)
                 {
@@ -46845,6 +47529,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listConstraints_args implements org.apache.thrift.TBase<listConstraints_args, listConstraints_args._Fields>, java.io.Serializable, Cloneable, Comparable<listConstraints_args>   {
@@ -46853,24 +47540,21 @@
     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 TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", 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 listConstraints_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new listConstraints_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listConstraints_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listConstraints_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // 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"),
       TABLE_NAME((short)2, "tableName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -46895,21 +47579,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -46918,20 +47602,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listConstraints_args.class, metaDataMap);
     }
 
@@ -46939,8 +47623,8 @@
     }
 
     public listConstraints_args(
-      ByteBuffer login,
-      String tableName)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -46974,16 +47658,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public listConstraints_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public listConstraints_args setLogin(ByteBuffer login) {
+    public listConstraints_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -47003,11 +47687,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public listConstraints_args setTableName(String tableName) {
+    public listConstraints_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -47027,13 +47711,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -47041,14 +47729,14 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -47057,13 +47745,13 @@
         return getTableName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -47072,11 +47760,11 @@
       case TABLE_NAME:
         return isSetTableName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listConstraints_args)
@@ -47087,6 +47775,8 @@
     public boolean equals(listConstraints_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -47111,19 +47801,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -47134,7 +47822,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -47144,7 +47832,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -47162,16 +47850,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listConstraints_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listConstraints_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -47206,7 +47894,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -47214,13 +47902,13 @@
       }
     }
 
-    private static class listConstraints_argsStandardSchemeFactory implements SchemeFactory {
+    private static class listConstraints_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listConstraints_argsStandardScheme getScheme() {
         return new listConstraints_argsStandardScheme();
       }
     }
 
-    private static class listConstraints_argsStandardScheme extends StandardScheme<listConstraints_args> {
+    private static class listConstraints_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<listConstraints_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, listConstraints_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -47279,18 +47967,18 @@
 
     }
 
-    private static class listConstraints_argsTupleSchemeFactory implements SchemeFactory {
+    private static class listConstraints_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listConstraints_argsTupleScheme getScheme() {
         return new listConstraints_argsTupleScheme();
       }
     }
 
-    private static class listConstraints_argsTupleScheme extends TupleScheme<listConstraints_args> {
+    private static class listConstraints_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<listConstraints_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, listConstraints_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -47308,8 +47996,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, listConstraints_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -47321,6 +48009,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listConstraints_result implements org.apache.thrift.TBase<listConstraints_result, listConstraints_result._Fields>, java.io.Serializable, Cloneable, Comparable<listConstraints_result>   {
@@ -47331,13 +48022,10 @@
     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 listConstraints_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new listConstraints_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listConstraints_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listConstraints_resultTupleSchemeFactory();
 
-    public Map<String,Integer> success; // required
+    public java.util.Map<java.lang.String,java.lang.Integer> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -47349,10 +48037,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -47381,21 +48069,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -47404,26 +48092,26 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listConstraints_result.class, metaDataMap);
     }
 
@@ -47431,7 +48119,7 @@
     }
 
     public listConstraints_result(
-      Map<String,Integer> success,
+      java.util.Map<java.lang.String,java.lang.Integer> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -47448,7 +48136,7 @@
      */
     public listConstraints_result(listConstraints_result other) {
       if (other.isSetSuccess()) {
-        Map<String,Integer> __this__success = new HashMap<String,Integer>(other.success);
+        java.util.Map<java.lang.String,java.lang.Integer> __this__success = new java.util.HashMap<java.lang.String,java.lang.Integer>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -47478,18 +48166,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, int val) {
+    public void putToSuccess(java.lang.String key, int val) {
       if (this.success == null) {
-        this.success = new HashMap<String,Integer>();
+        this.success = new java.util.HashMap<java.lang.String,java.lang.Integer>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,Integer> getSuccess() {
+    public java.util.Map<java.lang.String,java.lang.Integer> getSuccess() {
       return this.success;
     }
 
-    public listConstraints_result setSuccess(Map<String,Integer> success) {
+    public listConstraints_result setSuccess(java.util.Map<java.lang.String,java.lang.Integer> success) {
       this.success = success;
       return this;
     }
@@ -47581,13 +48269,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,Integer>)value);
+          setSuccess((java.util.Map<java.lang.String,java.lang.Integer>)value);
         }
         break;
 
@@ -47618,7 +48306,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -47633,13 +48321,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -47652,11 +48340,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listConstraints_result)
@@ -47667,6 +48355,8 @@
     public boolean equals(listConstraints_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -47709,29 +48399,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -47742,7 +48428,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -47752,7 +48438,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -47762,7 +48448,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -47772,7 +48458,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -47790,16 +48476,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listConstraints_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listConstraints_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -47850,7 +48536,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -47858,13 +48544,13 @@
       }
     }
 
-    private static class listConstraints_resultStandardSchemeFactory implements SchemeFactory {
+    private static class listConstraints_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listConstraints_resultStandardScheme getScheme() {
         return new listConstraints_resultStandardScheme();
       }
     }
 
-    private static class listConstraints_resultStandardScheme extends StandardScheme<listConstraints_result> {
+    private static class listConstraints_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<listConstraints_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, listConstraints_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -47880,8 +48566,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map310 = iprot.readMapBegin();
-                  struct.success = new HashMap<String,Integer>(2*_map310.size);
-                  String _key311;
+                  struct.success = new java.util.HashMap<java.lang.String,java.lang.Integer>(2*_map310.size);
+                  java.lang.String _key311;
                   int _val312;
                   for (int _i313 = 0; _i313 < _map310.size; ++_i313)
                   {
@@ -47942,7 +48628,7 @@
           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> _iter314 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter314 : struct.success.entrySet())
             {
               oprot.writeString(_iter314.getKey());
               oprot.writeI32(_iter314.getValue());
@@ -47972,18 +48658,18 @@
 
     }
 
-    private static class listConstraints_resultTupleSchemeFactory implements SchemeFactory {
+    private static class listConstraints_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listConstraints_resultTupleScheme getScheme() {
         return new listConstraints_resultTupleScheme();
       }
     }
 
-    private static class listConstraints_resultTupleScheme extends TupleScheme<listConstraints_result> {
+    private static class listConstraints_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<listConstraints_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, listConstraints_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -48000,7 +48686,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, Integer> _iter315 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter315 : struct.success.entrySet())
             {
               oprot.writeString(_iter315.getKey());
               oprot.writeI32(_iter315.getValue());
@@ -48020,13 +48706,13 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, listConstraints_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           {
             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);
-            String _key317;
+            struct.success = new java.util.HashMap<java.lang.String,java.lang.Integer>(2*_map316.size);
+            java.lang.String _key317;
             int _val318;
             for (int _i319 = 0; _i319 < _map316.size; ++_i319)
             {
@@ -48055,6 +48741,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class mergeTablets_args implements org.apache.thrift.TBase<mergeTablets_args, mergeTablets_args._Fields>, java.io.Serializable, Cloneable, Comparable<mergeTablets_args>   {
@@ -48065,16 +48754,13 @@
     private static final org.apache.thrift.protocol.TField START_ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("startRow", org.apache.thrift.protocol.TType.STRING, (short)3);
     private static final org.apache.thrift.protocol.TField END_ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("endRow", 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 mergeTablets_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new mergeTablets_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new mergeTablets_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new mergeTablets_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public ByteBuffer startRow; // required
-    public ByteBuffer endRow; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.nio.ByteBuffer startRow; // required
+    public java.nio.ByteBuffer endRow; // 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 {
@@ -48083,10 +48769,10 @@
       START_ROW((short)3, "startRow"),
       END_ROW((short)4, "endRow");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -48115,21 +48801,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -48138,15 +48824,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -48155,7 +48841,7 @@
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
       tmpMap.put(_Fields.END_ROW, new org.apache.thrift.meta_data.FieldMetaData("endRow", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(mergeTablets_args.class, metaDataMap);
     }
 
@@ -48163,10 +48849,10 @@
     }
 
     public mergeTablets_args(
-      ByteBuffer login,
-      String tableName,
-      ByteBuffer startRow,
-      ByteBuffer endRow)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.nio.ByteBuffer startRow,
+      java.nio.ByteBuffer endRow)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -48210,16 +48896,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public mergeTablets_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public mergeTablets_args setLogin(ByteBuffer login) {
+    public mergeTablets_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -48239,11 +48925,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public mergeTablets_args setTableName(String tableName) {
+    public mergeTablets_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -48268,16 +48954,16 @@
       return startRow == null ? null : startRow.array();
     }
 
-    public ByteBuffer bufferForStartRow() {
+    public java.nio.ByteBuffer bufferForStartRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(startRow);
     }
 
     public mergeTablets_args setStartRow(byte[] startRow) {
-      this.startRow = startRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(startRow, startRow.length));
+      this.startRow = startRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(startRow.clone());
       return this;
     }
 
-    public mergeTablets_args setStartRow(ByteBuffer startRow) {
+    public mergeTablets_args setStartRow(java.nio.ByteBuffer startRow) {
       this.startRow = org.apache.thrift.TBaseHelper.copyBinary(startRow);
       return this;
     }
@@ -48302,16 +48988,16 @@
       return endRow == null ? null : endRow.array();
     }
 
-    public ByteBuffer bufferForEndRow() {
+    public java.nio.ByteBuffer bufferForEndRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(endRow);
     }
 
     public mergeTablets_args setEndRow(byte[] endRow) {
-      this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
+      this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
       return this;
     }
 
-    public mergeTablets_args setEndRow(ByteBuffer endRow) {
+    public mergeTablets_args setEndRow(java.nio.ByteBuffer endRow) {
       this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
       return this;
     }
@@ -48331,13 +49017,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -48345,7 +49035,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -48353,7 +49043,11 @@
         if (value == null) {
           unsetStartRow();
         } else {
-          setStartRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setStartRow((byte[])value);
+          } else {
+            setStartRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -48361,14 +49055,18 @@
         if (value == null) {
           unsetEndRow();
         } else {
-          setEndRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setEndRow((byte[])value);
+          } else {
+            setEndRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -48383,13 +49081,13 @@
         return getEndRow();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -48402,11 +49100,11 @@
       case END_ROW:
         return isSetEndRow();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof mergeTablets_args)
@@ -48417,6 +49115,8 @@
     public boolean equals(mergeTablets_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -48459,29 +49159,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_startRow = true && (isSetStartRow());
-      list.add(present_startRow);
-      if (present_startRow)
-        list.add(startRow);
+      hashCode = hashCode * 8191 + ((isSetStartRow()) ? 131071 : 524287);
+      if (isSetStartRow())
+        hashCode = hashCode * 8191 + startRow.hashCode();
 
-      boolean present_endRow = true && (isSetEndRow());
-      list.add(present_endRow);
-      if (present_endRow)
-        list.add(endRow);
+      hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
+      if (isSetEndRow())
+        hashCode = hashCode * 8191 + endRow.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -48492,7 +49188,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -48502,7 +49198,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -48512,7 +49208,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetStartRow()).compareTo(other.isSetStartRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -48522,7 +49218,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -48540,16 +49236,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("mergeTablets_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("mergeTablets_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -48600,7 +49296,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -48608,13 +49304,13 @@
       }
     }
 
-    private static class mergeTablets_argsStandardSchemeFactory implements SchemeFactory {
+    private static class mergeTablets_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public mergeTablets_argsStandardScheme getScheme() {
         return new mergeTablets_argsStandardScheme();
       }
     }
 
-    private static class mergeTablets_argsStandardScheme extends StandardScheme<mergeTablets_args> {
+    private static class mergeTablets_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<mergeTablets_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, mergeTablets_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -48699,18 +49395,18 @@
 
     }
 
-    private static class mergeTablets_argsTupleSchemeFactory implements SchemeFactory {
+    private static class mergeTablets_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public mergeTablets_argsTupleScheme getScheme() {
         return new mergeTablets_argsTupleScheme();
       }
     }
 
-    private static class mergeTablets_argsTupleScheme extends TupleScheme<mergeTablets_args> {
+    private static class mergeTablets_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<mergeTablets_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, mergeTablets_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -48740,8 +49436,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, mergeTablets_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -48761,6 +49457,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class mergeTablets_result implements org.apache.thrift.TBase<mergeTablets_result, mergeTablets_result._Fields>, java.io.Serializable, Cloneable, Comparable<mergeTablets_result>   {
@@ -48770,11 +49469,8 @@
     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 mergeTablets_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new mergeTablets_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new mergeTablets_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new mergeTablets_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -48786,10 +49482,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -48816,21 +49512,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -48839,22 +49535,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(mergeTablets_result.class, metaDataMap);
     }
 
@@ -48970,7 +49666,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -48999,7 +49695,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -49011,13 +49707,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -49028,11 +49724,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof mergeTablets_result)
@@ -49043,6 +49739,8 @@
     public boolean equals(mergeTablets_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -49076,24 +49774,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -49104,7 +49799,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -49114,7 +49809,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -49124,7 +49819,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -49142,16 +49837,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("mergeTablets_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("mergeTablets_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -49194,7 +49889,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -49202,13 +49897,13 @@
       }
     }
 
-    private static class mergeTablets_resultStandardSchemeFactory implements SchemeFactory {
+    private static class mergeTablets_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public mergeTablets_resultStandardScheme getScheme() {
         return new mergeTablets_resultStandardScheme();
       }
     }
 
-    private static class mergeTablets_resultStandardScheme extends StandardScheme<mergeTablets_result> {
+    private static class mergeTablets_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<mergeTablets_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, mergeTablets_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -49283,18 +49978,18 @@
 
     }
 
-    private static class mergeTablets_resultTupleSchemeFactory implements SchemeFactory {
+    private static class mergeTablets_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public mergeTablets_resultTupleScheme getScheme() {
         return new mergeTablets_resultTupleScheme();
       }
     }
 
-    private static class mergeTablets_resultTupleScheme extends TupleScheme<mergeTablets_result> {
+    private static class mergeTablets_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<mergeTablets_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, mergeTablets_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -49318,8 +50013,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, mergeTablets_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -49338,6 +50033,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class offlineTable_args implements org.apache.thrift.TBase<offlineTable_args, offlineTable_args._Fields>, java.io.Serializable, Cloneable, Comparable<offlineTable_args>   {
@@ -49347,14 +50045,11 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField WAIT_FIELD_DESC = new org.apache.thrift.protocol.TField("wait", org.apache.thrift.protocol.TType.BOOL, (short)3);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new offlineTable_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new offlineTable_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new offlineTable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new offlineTable_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public boolean wait; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -49363,10 +50058,10 @@
       TABLE_NAME((short)2, "tableName"),
       WAIT((short)3, "wait");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -49393,21 +50088,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -49416,7 +50111,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -49424,16 +50119,16 @@
     // isset id assignments
     private static final int __WAIT_ISSET_ID = 0;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.WAIT, new org.apache.thrift.meta_data.FieldMetaData("wait", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(offlineTable_args.class, metaDataMap);
     }
 
@@ -49443,8 +50138,8 @@
     }
 
     public offlineTable_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       boolean wait)
     {
       this();
@@ -49485,16 +50180,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public offlineTable_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public offlineTable_args setLogin(ByteBuffer login) {
+    public offlineTable_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -49514,11 +50209,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public offlineTable_args setTableName(String tableName) {
+    public offlineTable_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -49549,25 +50244,29 @@
     }
 
     public void unsetWait() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __WAIT_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __WAIT_ISSET_ID);
     }
 
     /** Returns true if field wait is set (has been assigned a value) and false otherwise */
     public boolean isSetWait() {
-      return EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
     }
 
     public void setWaitIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -49575,7 +50274,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -49583,14 +50282,14 @@
         if (value == null) {
           unsetWait();
         } else {
-          setWait((Boolean)value);
+          setWait((java.lang.Boolean)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -49602,13 +50301,13 @@
         return isWait();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -49619,11 +50318,11 @@
       case WAIT:
         return isSetWait();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof offlineTable_args)
@@ -49634,6 +50333,8 @@
     public boolean equals(offlineTable_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -49667,24 +50368,19 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_wait = true;
-      list.add(present_wait);
-      if (present_wait)
-        list.add(wait);
+      hashCode = hashCode * 8191 + ((wait) ? 131071 : 524287);
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -49695,7 +50391,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -49705,7 +50401,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -49715,7 +50411,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
+      lastComparison = java.lang.Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -49733,16 +50429,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("offlineTable_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("offlineTable_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -49781,7 +50477,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -49791,13 +50487,13 @@
       }
     }
 
-    private static class offlineTable_argsStandardSchemeFactory implements SchemeFactory {
+    private static class offlineTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public offlineTable_argsStandardScheme getScheme() {
         return new offlineTable_argsStandardScheme();
       }
     }
 
-    private static class offlineTable_argsStandardScheme extends StandardScheme<offlineTable_args> {
+    private static class offlineTable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<offlineTable_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, offlineTable_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -49867,18 +50563,18 @@
 
     }
 
-    private static class offlineTable_argsTupleSchemeFactory implements SchemeFactory {
+    private static class offlineTable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public offlineTable_argsTupleScheme getScheme() {
         return new offlineTable_argsTupleScheme();
       }
     }
 
-    private static class offlineTable_argsTupleScheme extends TupleScheme<offlineTable_args> {
+    private static class offlineTable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<offlineTable_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, offlineTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -49902,8 +50598,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, offlineTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -49919,6 +50615,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class offlineTable_result implements org.apache.thrift.TBase<offlineTable_result, offlineTable_result._Fields>, java.io.Serializable, Cloneable, Comparable<offlineTable_result>   {
@@ -49928,11 +50627,8 @@
     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 offlineTable_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new offlineTable_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new offlineTable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new offlineTable_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -49944,10 +50640,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -49974,21 +50670,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -49997,22 +50693,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(offlineTable_result.class, metaDataMap);
     }
 
@@ -50128,7 +50824,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -50157,7 +50853,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -50169,13 +50865,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -50186,11 +50882,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof offlineTable_result)
@@ -50201,6 +50897,8 @@
     public boolean equals(offlineTable_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -50234,24 +50932,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -50262,7 +50957,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -50272,7 +50967,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -50282,7 +50977,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -50300,16 +50995,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("offlineTable_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("offlineTable_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -50352,7 +51047,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -50360,13 +51055,13 @@
       }
     }
 
-    private static class offlineTable_resultStandardSchemeFactory implements SchemeFactory {
+    private static class offlineTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public offlineTable_resultStandardScheme getScheme() {
         return new offlineTable_resultStandardScheme();
       }
     }
 
-    private static class offlineTable_resultStandardScheme extends StandardScheme<offlineTable_result> {
+    private static class offlineTable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<offlineTable_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, offlineTable_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -50441,18 +51136,18 @@
 
     }
 
-    private static class offlineTable_resultTupleSchemeFactory implements SchemeFactory {
+    private static class offlineTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public offlineTable_resultTupleScheme getScheme() {
         return new offlineTable_resultTupleScheme();
       }
     }
 
-    private static class offlineTable_resultTupleScheme extends TupleScheme<offlineTable_result> {
+    private static class offlineTable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<offlineTable_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, offlineTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -50476,8 +51171,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, offlineTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -50496,6 +51191,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class onlineTable_args implements org.apache.thrift.TBase<onlineTable_args, onlineTable_args._Fields>, java.io.Serializable, Cloneable, Comparable<onlineTable_args>   {
@@ -50505,14 +51203,11 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField WAIT_FIELD_DESC = new org.apache.thrift.protocol.TField("wait", org.apache.thrift.protocol.TType.BOOL, (short)3);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new onlineTable_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new onlineTable_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new onlineTable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new onlineTable_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public boolean wait; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -50521,10 +51216,10 @@
       TABLE_NAME((short)2, "tableName"),
       WAIT((short)3, "wait");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -50551,21 +51246,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -50574,7 +51269,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -50582,16 +51277,16 @@
     // isset id assignments
     private static final int __WAIT_ISSET_ID = 0;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.WAIT, new org.apache.thrift.meta_data.FieldMetaData("wait", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(onlineTable_args.class, metaDataMap);
     }
 
@@ -50601,8 +51296,8 @@
     }
 
     public onlineTable_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       boolean wait)
     {
       this();
@@ -50643,16 +51338,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public onlineTable_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public onlineTable_args setLogin(ByteBuffer login) {
+    public onlineTable_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -50672,11 +51367,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public onlineTable_args setTableName(String tableName) {
+    public onlineTable_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -50707,25 +51402,29 @@
     }
 
     public void unsetWait() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __WAIT_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __WAIT_ISSET_ID);
     }
 
     /** Returns true if field wait is set (has been assigned a value) and false otherwise */
     public boolean isSetWait() {
-      return EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __WAIT_ISSET_ID);
     }
 
     public void setWaitIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __WAIT_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -50733,7 +51432,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -50741,14 +51440,14 @@
         if (value == null) {
           unsetWait();
         } else {
-          setWait((Boolean)value);
+          setWait((java.lang.Boolean)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -50760,13 +51459,13 @@
         return isWait();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -50777,11 +51476,11 @@
       case WAIT:
         return isSetWait();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof onlineTable_args)
@@ -50792,6 +51491,8 @@
     public boolean equals(onlineTable_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -50825,24 +51526,19 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_wait = true;
-      list.add(present_wait);
-      if (present_wait)
-        list.add(wait);
+      hashCode = hashCode * 8191 + ((wait) ? 131071 : 524287);
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -50853,7 +51549,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -50863,7 +51559,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -50873,7 +51569,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
+      lastComparison = java.lang.Boolean.valueOf(isSetWait()).compareTo(other.isSetWait());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -50891,16 +51587,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("onlineTable_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("onlineTable_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -50939,7 +51635,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -50949,13 +51645,13 @@
       }
     }
 
-    private static class onlineTable_argsStandardSchemeFactory implements SchemeFactory {
+    private static class onlineTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public onlineTable_argsStandardScheme getScheme() {
         return new onlineTable_argsStandardScheme();
       }
     }
 
-    private static class onlineTable_argsStandardScheme extends StandardScheme<onlineTable_args> {
+    private static class onlineTable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<onlineTable_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, onlineTable_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -51025,18 +51721,18 @@
 
     }
 
-    private static class onlineTable_argsTupleSchemeFactory implements SchemeFactory {
+    private static class onlineTable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public onlineTable_argsTupleScheme getScheme() {
         return new onlineTable_argsTupleScheme();
       }
     }
 
-    private static class onlineTable_argsTupleScheme extends TupleScheme<onlineTable_args> {
+    private static class onlineTable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<onlineTable_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, onlineTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -51060,8 +51756,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, onlineTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -51077,6 +51773,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class onlineTable_result implements org.apache.thrift.TBase<onlineTable_result, onlineTable_result._Fields>, java.io.Serializable, Cloneable, Comparable<onlineTable_result>   {
@@ -51086,11 +51785,8 @@
     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 onlineTable_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new onlineTable_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new onlineTable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new onlineTable_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -51102,10 +51798,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -51132,21 +51828,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -51155,22 +51851,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(onlineTable_result.class, metaDataMap);
     }
 
@@ -51286,7 +51982,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -51315,7 +52011,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -51327,13 +52023,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -51344,11 +52040,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof onlineTable_result)
@@ -51359,6 +52055,8 @@
     public boolean equals(onlineTable_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -51392,24 +52090,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -51420,7 +52115,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -51430,7 +52125,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -51440,7 +52135,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -51458,16 +52153,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("onlineTable_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("onlineTable_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -51510,7 +52205,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -51518,13 +52213,13 @@
       }
     }
 
-    private static class onlineTable_resultStandardSchemeFactory implements SchemeFactory {
+    private static class onlineTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public onlineTable_resultStandardScheme getScheme() {
         return new onlineTable_resultStandardScheme();
       }
     }
 
-    private static class onlineTable_resultStandardScheme extends StandardScheme<onlineTable_result> {
+    private static class onlineTable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<onlineTable_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, onlineTable_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -51599,18 +52294,18 @@
 
     }
 
-    private static class onlineTable_resultTupleSchemeFactory implements SchemeFactory {
+    private static class onlineTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public onlineTable_resultTupleScheme getScheme() {
         return new onlineTable_resultTupleScheme();
       }
     }
 
-    private static class onlineTable_resultTupleScheme extends TupleScheme<onlineTable_result> {
+    private static class onlineTable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<onlineTable_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, onlineTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -51634,8 +52329,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, onlineTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -51654,6 +52349,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeConstraint_args implements org.apache.thrift.TBase<removeConstraint_args, removeConstraint_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeConstraint_args>   {
@@ -51663,14 +52361,11 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField CONSTRAINT_FIELD_DESC = new org.apache.thrift.protocol.TField("constraint", 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 removeConstraint_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new removeConstraint_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeConstraint_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeConstraint_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public int constraint; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -51679,10 +52374,10 @@
       TABLE_NAME((short)2, "tableName"),
       CONSTRAINT((short)3, "constraint");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -51709,21 +52404,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -51732,7 +52427,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -51740,16 +52435,16 @@
     // isset id assignments
     private static final int __CONSTRAINT_ISSET_ID = 0;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.CONSTRAINT, new org.apache.thrift.meta_data.FieldMetaData("constraint", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeConstraint_args.class, metaDataMap);
     }
 
@@ -51757,8 +52452,8 @@
     }
 
     public removeConstraint_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       int constraint)
     {
       this();
@@ -51799,16 +52494,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public removeConstraint_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public removeConstraint_args setLogin(ByteBuffer login) {
+    public removeConstraint_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -51828,11 +52523,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public removeConstraint_args setTableName(String tableName) {
+    public removeConstraint_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -51863,25 +52558,29 @@
     }
 
     public void unsetConstraint() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __CONSTRAINT_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CONSTRAINT_ISSET_ID);
     }
 
     /** Returns true if field constraint is set (has been assigned a value) and false otherwise */
     public boolean isSetConstraint() {
-      return EncodingUtils.testBit(__isset_bitfield, __CONSTRAINT_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CONSTRAINT_ISSET_ID);
     }
 
     public void setConstraintIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __CONSTRAINT_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CONSTRAINT_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -51889,7 +52588,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -51897,14 +52596,14 @@
         if (value == null) {
           unsetConstraint();
         } else {
-          setConstraint((Integer)value);
+          setConstraint((java.lang.Integer)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -51916,13 +52615,13 @@
         return getConstraint();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -51933,11 +52632,11 @@
       case CONSTRAINT:
         return isSetConstraint();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeConstraint_args)
@@ -51948,6 +52647,8 @@
     public boolean equals(removeConstraint_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -51981,24 +52682,19 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_constraint = true;
-      list.add(present_constraint);
-      if (present_constraint)
-        list.add(constraint);
+      hashCode = hashCode * 8191 + constraint;
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -52009,7 +52705,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -52019,7 +52715,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -52029,7 +52725,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetConstraint()).compareTo(other.isSetConstraint());
+      lastComparison = java.lang.Boolean.valueOf(isSetConstraint()).compareTo(other.isSetConstraint());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -52047,16 +52743,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeConstraint_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeConstraint_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -52095,7 +52791,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -52105,13 +52801,13 @@
       }
     }
 
-    private static class removeConstraint_argsStandardSchemeFactory implements SchemeFactory {
+    private static class removeConstraint_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeConstraint_argsStandardScheme getScheme() {
         return new removeConstraint_argsStandardScheme();
       }
     }
 
-    private static class removeConstraint_argsStandardScheme extends StandardScheme<removeConstraint_args> {
+    private static class removeConstraint_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeConstraint_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, removeConstraint_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -52181,18 +52877,18 @@
 
     }
 
-    private static class removeConstraint_argsTupleSchemeFactory implements SchemeFactory {
+    private static class removeConstraint_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeConstraint_argsTupleScheme getScheme() {
         return new removeConstraint_argsTupleScheme();
       }
     }
 
-    private static class removeConstraint_argsTupleScheme extends TupleScheme<removeConstraint_args> {
+    private static class removeConstraint_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeConstraint_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, removeConstraint_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -52216,8 +52912,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, removeConstraint_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -52233,6 +52929,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeConstraint_result implements org.apache.thrift.TBase<removeConstraint_result, removeConstraint_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeConstraint_result>   {
@@ -52242,11 +52941,8 @@
     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 removeConstraint_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new removeConstraint_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeConstraint_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeConstraint_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -52258,10 +52954,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -52288,21 +52984,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -52311,22 +53007,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeConstraint_result.class, metaDataMap);
     }
 
@@ -52442,7 +53138,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -52471,7 +53167,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -52483,13 +53179,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -52500,11 +53196,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeConstraint_result)
@@ -52515,6 +53211,8 @@
     public boolean equals(removeConstraint_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -52548,24 +53246,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -52576,7 +53271,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -52586,7 +53281,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -52596,7 +53291,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -52614,16 +53309,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeConstraint_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeConstraint_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -52666,7 +53361,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -52674,13 +53369,13 @@
       }
     }
 
-    private static class removeConstraint_resultStandardSchemeFactory implements SchemeFactory {
+    private static class removeConstraint_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeConstraint_resultStandardScheme getScheme() {
         return new removeConstraint_resultStandardScheme();
       }
     }
 
-    private static class removeConstraint_resultStandardScheme extends StandardScheme<removeConstraint_result> {
+    private static class removeConstraint_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeConstraint_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, removeConstraint_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -52755,18 +53450,18 @@
 
     }
 
-    private static class removeConstraint_resultTupleSchemeFactory implements SchemeFactory {
+    private static class removeConstraint_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeConstraint_resultTupleScheme getScheme() {
         return new removeConstraint_resultTupleScheme();
       }
     }
 
-    private static class removeConstraint_resultTupleScheme extends TupleScheme<removeConstraint_result> {
+    private static class removeConstraint_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeConstraint_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, removeConstraint_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -52790,8 +53485,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, removeConstraint_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -52810,6 +53505,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeIterator_args implements org.apache.thrift.TBase<removeIterator_args, removeIterator_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeIterator_args>   {
@@ -52820,16 +53518,13 @@
     private static final org.apache.thrift.protocol.TField ITER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("iterName", 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 removeIterator_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new removeIterator_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeIterator_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeIterator_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public String iterName; // required
-    public Set<IteratorScope> scopes; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.lang.String iterName; // required
+    public java.util.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 {
@@ -52838,10 +53533,10 @@
       ITER_NAME((short)3, "iterName"),
       SCOPES((short)4, "scopes");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -52870,21 +53565,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -52893,15 +53588,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -52911,7 +53606,7 @@
       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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeIterator_args.class, metaDataMap);
     }
 
@@ -52919,10 +53614,10 @@
     }
 
     public removeIterator_args(
-      ByteBuffer login,
-      String tableName,
-      String iterName,
-      Set<IteratorScope> scopes)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.lang.String iterName,
+      java.util.Set<IteratorScope> scopes)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -52945,7 +53640,7 @@
         this.iterName = other.iterName;
       }
       if (other.isSetScopes()) {
-        Set<IteratorScope> __this__scopes = new HashSet<IteratorScope>(other.scopes.size());
+        java.util.Set<IteratorScope> __this__scopes = new java.util.HashSet<IteratorScope>(other.scopes.size());
         for (IteratorScope other_element : other.scopes) {
           __this__scopes.add(other_element);
         }
@@ -52970,16 +53665,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public removeIterator_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public removeIterator_args setLogin(ByteBuffer login) {
+    public removeIterator_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -52999,11 +53694,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public removeIterator_args setTableName(String tableName) {
+    public removeIterator_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -53023,11 +53718,11 @@
       }
     }
 
-    public String getIterName() {
+    public java.lang.String getIterName() {
       return this.iterName;
     }
 
-    public removeIterator_args setIterName(String iterName) {
+    public removeIterator_args setIterName(java.lang.String iterName) {
       this.iterName = iterName;
       return this;
     }
@@ -53057,16 +53752,16 @@
 
     public void addToScopes(IteratorScope elem) {
       if (this.scopes == null) {
-        this.scopes = new HashSet<IteratorScope>();
+        this.scopes = new java.util.HashSet<IteratorScope>();
       }
       this.scopes.add(elem);
     }
 
-    public Set<IteratorScope> getScopes() {
+    public java.util.Set<IteratorScope> getScopes() {
       return this.scopes;
     }
 
-    public removeIterator_args setScopes(Set<IteratorScope> scopes) {
+    public removeIterator_args setScopes(java.util.Set<IteratorScope> scopes) {
       this.scopes = scopes;
       return this;
     }
@@ -53086,13 +53781,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -53100,7 +53799,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -53108,7 +53807,7 @@
         if (value == null) {
           unsetIterName();
         } else {
-          setIterName((String)value);
+          setIterName((java.lang.String)value);
         }
         break;
 
@@ -53116,14 +53815,14 @@
         if (value == null) {
           unsetScopes();
         } else {
-          setScopes((Set<IteratorScope>)value);
+          setScopes((java.util.Set<IteratorScope>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -53138,13 +53837,13 @@
         return getScopes();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -53157,11 +53856,11 @@
       case SCOPES:
         return isSetScopes();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeIterator_args)
@@ -53172,6 +53871,8 @@
     public boolean equals(removeIterator_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -53214,29 +53915,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_iterName = true && (isSetIterName());
-      list.add(present_iterName);
-      if (present_iterName)
-        list.add(iterName);
+      hashCode = hashCode * 8191 + ((isSetIterName()) ? 131071 : 524287);
+      if (isSetIterName())
+        hashCode = hashCode * 8191 + iterName.hashCode();
 
-      boolean present_scopes = true && (isSetScopes());
-      list.add(present_scopes);
-      if (present_scopes)
-        list.add(scopes);
+      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
+      if (isSetScopes())
+        hashCode = hashCode * 8191 + scopes.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -53247,7 +53944,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -53257,7 +53954,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -53267,7 +53964,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetIterName()).compareTo(other.isSetIterName());
+      lastComparison = java.lang.Boolean.valueOf(isSetIterName()).compareTo(other.isSetIterName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -53277,7 +53974,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
+      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -53295,16 +53992,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeIterator_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeIterator_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -53355,7 +54052,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -53363,13 +54060,13 @@
       }
     }
 
-    private static class removeIterator_argsStandardSchemeFactory implements SchemeFactory {
+    private static class removeIterator_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeIterator_argsStandardScheme getScheme() {
         return new removeIterator_argsStandardScheme();
       }
     }
 
-    private static class removeIterator_argsStandardScheme extends StandardScheme<removeIterator_args> {
+    private static class removeIterator_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeIterator_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, removeIterator_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -53409,7 +54106,7 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set320 = iprot.readSetBegin();
-                  struct.scopes = new HashSet<IteratorScope>(2*_set320.size);
+                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set320.size);
                   IteratorScope _elem321;
                   for (int _i322 = 0; _i322 < _set320.size; ++_i322)
                   {
@@ -53471,18 +54168,18 @@
 
     }
 
-    private static class removeIterator_argsTupleSchemeFactory implements SchemeFactory {
+    private static class removeIterator_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeIterator_argsTupleScheme getScheme() {
         return new removeIterator_argsTupleScheme();
       }
     }
 
-    private static class removeIterator_argsTupleScheme extends TupleScheme<removeIterator_args> {
+    private static class removeIterator_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeIterator_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, removeIterator_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -53518,8 +54215,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, removeIterator_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -53535,7 +54232,7 @@
         if (incoming.get(3)) {
           {
             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);
+            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set325.size);
             IteratorScope _elem326;
             for (int _i327 = 0; _i327 < _set325.size; ++_i327)
             {
@@ -53548,6 +54245,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeIterator_result implements org.apache.thrift.TBase<removeIterator_result, removeIterator_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeIterator_result>   {
@@ -53557,11 +54257,8 @@
     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 removeIterator_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new removeIterator_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeIterator_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeIterator_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -53573,10 +54270,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -53603,21 +54300,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -53626,22 +54323,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeIterator_result.class, metaDataMap);
     }
 
@@ -53757,7 +54454,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -53786,7 +54483,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -53798,13 +54495,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -53815,11 +54512,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeIterator_result)
@@ -53830,6 +54527,8 @@
     public boolean equals(removeIterator_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -53863,24 +54562,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -53891,7 +54587,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -53901,7 +54597,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -53911,7 +54607,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -53929,16 +54625,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeIterator_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeIterator_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -53981,7 +54677,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -53989,13 +54685,13 @@
       }
     }
 
-    private static class removeIterator_resultStandardSchemeFactory implements SchemeFactory {
+    private static class removeIterator_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeIterator_resultStandardScheme getScheme() {
         return new removeIterator_resultStandardScheme();
       }
     }
 
-    private static class removeIterator_resultStandardScheme extends StandardScheme<removeIterator_result> {
+    private static class removeIterator_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeIterator_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, removeIterator_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -54070,18 +54766,18 @@
 
     }
 
-    private static class removeIterator_resultTupleSchemeFactory implements SchemeFactory {
+    private static class removeIterator_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeIterator_resultTupleScheme getScheme() {
         return new removeIterator_resultTupleScheme();
       }
     }
 
-    private static class removeIterator_resultTupleScheme extends TupleScheme<removeIterator_result> {
+    private static class removeIterator_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeIterator_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, removeIterator_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -54105,8 +54801,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, removeIterator_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -54125,6 +54821,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeTableProperty_args implements org.apache.thrift.TBase<removeTableProperty_args, removeTableProperty_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeTableProperty_args>   {
@@ -54134,15 +54833,12 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", 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 removeTableProperty_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new removeTableProperty_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeTableProperty_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeTableProperty_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public String property; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.lang.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 {
@@ -54150,10 +54846,10 @@
       TABLE_NAME((short)2, "tableName"),
       PROPERTY((short)3, "property");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -54180,21 +54876,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -54203,22 +54899,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", 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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeTableProperty_args.class, metaDataMap);
     }
 
@@ -54226,9 +54922,9 @@
     }
 
     public removeTableProperty_args(
-      ByteBuffer login,
-      String tableName,
-      String property)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.lang.String property)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -54267,16 +54963,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public removeTableProperty_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public removeTableProperty_args setLogin(ByteBuffer login) {
+    public removeTableProperty_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -54296,11 +54992,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public removeTableProperty_args setTableName(String tableName) {
+    public removeTableProperty_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -54320,11 +55016,11 @@
       }
     }
 
-    public String getProperty() {
+    public java.lang.String getProperty() {
       return this.property;
     }
 
-    public removeTableProperty_args setProperty(String property) {
+    public removeTableProperty_args setProperty(java.lang.String property) {
       this.property = property;
       return this;
     }
@@ -54344,13 +55040,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -54358,7 +55058,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -54366,14 +55066,14 @@
         if (value == null) {
           unsetProperty();
         } else {
-          setProperty((String)value);
+          setProperty((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -54385,13 +55085,13 @@
         return getProperty();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -54402,11 +55102,11 @@
       case PROPERTY:
         return isSetProperty();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeTableProperty_args)
@@ -54417,6 +55117,8 @@
     public boolean equals(removeTableProperty_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -54450,24 +55152,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_property = true && (isSetProperty());
-      list.add(present_property);
-      if (present_property)
-        list.add(property);
+      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
+      if (isSetProperty())
+        hashCode = hashCode * 8191 + property.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -54478,7 +55177,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -54488,7 +55187,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -54498,7 +55197,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
+      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -54516,16 +55215,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeTableProperty_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeTableProperty_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -54568,7 +55267,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -54576,13 +55275,13 @@
       }
     }
 
-    private static class removeTableProperty_argsStandardSchemeFactory implements SchemeFactory {
+    private static class removeTableProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeTableProperty_argsStandardScheme getScheme() {
         return new removeTableProperty_argsStandardScheme();
       }
     }
 
-    private static class removeTableProperty_argsStandardScheme extends StandardScheme<removeTableProperty_args> {
+    private static class removeTableProperty_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeTableProperty_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, removeTableProperty_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -54654,18 +55353,18 @@
 
     }
 
-    private static class removeTableProperty_argsTupleSchemeFactory implements SchemeFactory {
+    private static class removeTableProperty_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeTableProperty_argsTupleScheme getScheme() {
         return new removeTableProperty_argsTupleScheme();
       }
     }
 
-    private static class removeTableProperty_argsTupleScheme extends TupleScheme<removeTableProperty_args> {
+    private static class removeTableProperty_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeTableProperty_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, removeTableProperty_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -54689,8 +55388,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, removeTableProperty_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -54706,6 +55405,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeTableProperty_result implements org.apache.thrift.TBase<removeTableProperty_result, removeTableProperty_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeTableProperty_result>   {
@@ -54715,11 +55417,8 @@
     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 removeTableProperty_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new removeTableProperty_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeTableProperty_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeTableProperty_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -54731,10 +55430,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -54761,21 +55460,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -54784,22 +55483,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeTableProperty_result.class, metaDataMap);
     }
 
@@ -54915,7 +55614,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -54944,7 +55643,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -54956,13 +55655,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -54973,11 +55672,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeTableProperty_result)
@@ -54988,6 +55687,8 @@
     public boolean equals(removeTableProperty_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -55021,24 +55722,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -55049,7 +55747,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -55059,7 +55757,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -55069,7 +55767,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -55087,16 +55785,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeTableProperty_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeTableProperty_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -55139,7 +55837,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -55147,13 +55845,13 @@
       }
     }
 
-    private static class removeTableProperty_resultStandardSchemeFactory implements SchemeFactory {
+    private static class removeTableProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeTableProperty_resultStandardScheme getScheme() {
         return new removeTableProperty_resultStandardScheme();
       }
     }
 
-    private static class removeTableProperty_resultStandardScheme extends StandardScheme<removeTableProperty_result> {
+    private static class removeTableProperty_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeTableProperty_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, removeTableProperty_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -55228,18 +55926,18 @@
 
     }
 
-    private static class removeTableProperty_resultTupleSchemeFactory implements SchemeFactory {
+    private static class removeTableProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeTableProperty_resultTupleScheme getScheme() {
         return new removeTableProperty_resultTupleScheme();
       }
     }
 
-    private static class removeTableProperty_resultTupleScheme extends TupleScheme<removeTableProperty_result> {
+    private static class removeTableProperty_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeTableProperty_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, removeTableProperty_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -55263,8 +55961,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, removeTableProperty_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -55283,6 +55981,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class renameTable_args implements org.apache.thrift.TBase<renameTable_args, renameTable_args._Fields>, java.io.Serializable, Cloneable, Comparable<renameTable_args>   {
@@ -55292,15 +55993,12 @@
     private static final org.apache.thrift.protocol.TField OLD_TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("oldTableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField NEW_TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("newTableName", 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 renameTable_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new renameTable_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new renameTable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new renameTable_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String oldTableName; // required
-    public String newTableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String oldTableName; // required
+    public java.lang.String newTableName; // 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 {
@@ -55308,10 +56006,10 @@
       OLD_TABLE_NAME((short)2, "oldTableName"),
       NEW_TABLE_NAME((short)3, "newTableName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -55338,21 +56036,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -55361,22 +56059,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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_TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("oldTableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.NEW_TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("newTableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(renameTable_args.class, metaDataMap);
     }
 
@@ -55384,9 +56082,9 @@
     }
 
     public renameTable_args(
-      ByteBuffer login,
-      String oldTableName,
-      String newTableName)
+      java.nio.ByteBuffer login,
+      java.lang.String oldTableName,
+      java.lang.String newTableName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -55425,16 +56123,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public renameTable_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public renameTable_args setLogin(ByteBuffer login) {
+    public renameTable_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -55454,11 +56152,11 @@
       }
     }
 
-    public String getOldTableName() {
+    public java.lang.String getOldTableName() {
       return this.oldTableName;
     }
 
-    public renameTable_args setOldTableName(String oldTableName) {
+    public renameTable_args setOldTableName(java.lang.String oldTableName) {
       this.oldTableName = oldTableName;
       return this;
     }
@@ -55478,11 +56176,11 @@
       }
     }
 
-    public String getNewTableName() {
+    public java.lang.String getNewTableName() {
       return this.newTableName;
     }
 
-    public renameTable_args setNewTableName(String newTableName) {
+    public renameTable_args setNewTableName(java.lang.String newTableName) {
       this.newTableName = newTableName;
       return this;
     }
@@ -55502,13 +56200,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -55516,7 +56218,7 @@
         if (value == null) {
           unsetOldTableName();
         } else {
-          setOldTableName((String)value);
+          setOldTableName((java.lang.String)value);
         }
         break;
 
@@ -55524,14 +56226,14 @@
         if (value == null) {
           unsetNewTableName();
         } else {
-          setNewTableName((String)value);
+          setNewTableName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -55543,13 +56245,13 @@
         return getNewTableName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -55560,11 +56262,11 @@
       case NEW_TABLE_NAME:
         return isSetNewTableName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof renameTable_args)
@@ -55575,6 +56277,8 @@
     public boolean equals(renameTable_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -55608,24 +56312,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_oldTableName = true && (isSetOldTableName());
-      list.add(present_oldTableName);
-      if (present_oldTableName)
-        list.add(oldTableName);
+      hashCode = hashCode * 8191 + ((isSetOldTableName()) ? 131071 : 524287);
+      if (isSetOldTableName())
+        hashCode = hashCode * 8191 + oldTableName.hashCode();
 
-      boolean present_newTableName = true && (isSetNewTableName());
-      list.add(present_newTableName);
-      if (present_newTableName)
-        list.add(newTableName);
+      hashCode = hashCode * 8191 + ((isSetNewTableName()) ? 131071 : 524287);
+      if (isSetNewTableName())
+        hashCode = hashCode * 8191 + newTableName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -55636,7 +56337,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -55646,7 +56347,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOldTableName()).compareTo(other.isSetOldTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetOldTableName()).compareTo(other.isSetOldTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -55656,7 +56357,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNewTableName()).compareTo(other.isSetNewTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNewTableName()).compareTo(other.isSetNewTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -55674,16 +56375,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("renameTable_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("renameTable_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -55726,7 +56427,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -55734,13 +56435,13 @@
       }
     }
 
-    private static class renameTable_argsStandardSchemeFactory implements SchemeFactory {
+    private static class renameTable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public renameTable_argsStandardScheme getScheme() {
         return new renameTable_argsStandardScheme();
       }
     }
 
-    private static class renameTable_argsStandardScheme extends StandardScheme<renameTable_args> {
+    private static class renameTable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<renameTable_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, renameTable_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -55812,18 +56513,18 @@
 
     }
 
-    private static class renameTable_argsTupleSchemeFactory implements SchemeFactory {
+    private static class renameTable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public renameTable_argsTupleScheme getScheme() {
         return new renameTable_argsTupleScheme();
       }
     }
 
-    private static class renameTable_argsTupleScheme extends TupleScheme<renameTable_args> {
+    private static class renameTable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<renameTable_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, renameTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -55847,8 +56548,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, renameTable_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -55864,6 +56565,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class renameTable_result implements org.apache.thrift.TBase<renameTable_result, renameTable_result._Fields>, java.io.Serializable, Cloneable, Comparable<renameTable_result>   {
@@ -55874,11 +56578,8 @@
     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 renameTable_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new renameTable_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new renameTable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new renameTable_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -55892,10 +56593,10 @@
       OUCH3((short)3, "ouch3"),
       OUCH4((short)4, "ouch4");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -55924,21 +56625,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -55947,24 +56648,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableExistsException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(renameTable_result.class, metaDataMap);
     }
 
@@ -56110,7 +56811,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -56147,7 +56848,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -56162,13 +56863,13 @@
         return getOuch4();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -56181,11 +56882,11 @@
       case OUCH4:
         return isSetOuch4();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof renameTable_result)
@@ -56196,6 +56897,8 @@
     public boolean equals(renameTable_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -56238,29 +56941,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      boolean present_ouch4 = true && (isSetOuch4());
-      list.add(present_ouch4);
-      if (present_ouch4)
-        list.add(ouch4);
+      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
+      if (isSetOuch4())
+        hashCode = hashCode * 8191 + ouch4.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -56271,7 +56970,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -56281,7 +56980,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -56291,7 +56990,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -56301,7 +57000,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -56319,16 +57018,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("renameTable_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("renameTable_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -56379,7 +57078,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -56387,13 +57086,13 @@
       }
     }
 
-    private static class renameTable_resultStandardSchemeFactory implements SchemeFactory {
+    private static class renameTable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public renameTable_resultStandardScheme getScheme() {
         return new renameTable_resultStandardScheme();
       }
     }
 
-    private static class renameTable_resultStandardScheme extends StandardScheme<renameTable_result> {
+    private static class renameTable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<renameTable_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, renameTable_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -56482,18 +57181,18 @@
 
     }
 
-    private static class renameTable_resultTupleSchemeFactory implements SchemeFactory {
+    private static class renameTable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public renameTable_resultTupleScheme getScheme() {
         return new renameTable_resultTupleScheme();
       }
     }
 
-    private static class renameTable_resultTupleScheme extends TupleScheme<renameTable_result> {
+    private static class renameTable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<renameTable_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, renameTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -56523,8 +57222,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, renameTable_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -56548,6 +57247,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class setLocalityGroups_args implements org.apache.thrift.TBase<setLocalityGroups_args, setLocalityGroups_args._Fields>, java.io.Serializable, Cloneable, Comparable<setLocalityGroups_args>   {
@@ -56557,15 +57259,12 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField GROUPS_FIELD_DESC = new org.apache.thrift.protocol.TField("groups", org.apache.thrift.protocol.TType.MAP, (short)3);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new setLocalityGroups_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new setLocalityGroups_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new setLocalityGroups_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new setLocalityGroups_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public Map<String,Set<String>> groups; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups; // 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 {
@@ -56573,10 +57272,10 @@
       TABLE_NAME((short)2, "tableName"),
       GROUPS((short)3, "groups");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -56603,21 +57302,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -56626,15 +57325,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -56644,7 +57343,7 @@
               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.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setLocalityGroups_args.class, metaDataMap);
     }
 
@@ -56652,9 +57351,9 @@
     }
 
     public setLocalityGroups_args(
-      ByteBuffer login,
-      String tableName,
-      Map<String,Set<String>> groups)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -56673,15 +57372,15 @@
         this.tableName = other.tableName;
       }
       if (other.isSetGroups()) {
-        Map<String,Set<String>> __this__groups = new HashMap<String,Set<String>>(other.groups.size());
-        for (Map.Entry<String, Set<String>> other_element : other.groups.entrySet()) {
+        java.util.Map<java.lang.String,java.util.Set<java.lang.String>> __this__groups = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>(other.groups.size());
+        for (java.util.Map.Entry<java.lang.String, java.util.Set<java.lang.String>> other_element : other.groups.entrySet()) {
 
-          String other_element_key = other_element.getKey();
-          Set<String> other_element_value = other_element.getValue();
+          java.lang.String other_element_key = other_element.getKey();
+          java.util.Set<java.lang.String> other_element_value = other_element.getValue();
 
-          String __this__groups_copy_key = other_element_key;
+          java.lang.String __this__groups_copy_key = other_element_key;
 
-          Set<String> __this__groups_copy_value = new HashSet<String>(other_element_value);
+          java.util.Set<java.lang.String> __this__groups_copy_value = new java.util.HashSet<java.lang.String>(other_element_value);
 
           __this__groups.put(__this__groups_copy_key, __this__groups_copy_value);
         }
@@ -56705,16 +57404,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public setLocalityGroups_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public setLocalityGroups_args setLogin(ByteBuffer login) {
+    public setLocalityGroups_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -56734,11 +57433,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public setLocalityGroups_args setTableName(String tableName) {
+    public setLocalityGroups_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -56762,18 +57461,18 @@
       return (this.groups == null) ? 0 : this.groups.size();
     }
 
-    public void putToGroups(String key, Set<String> val) {
+    public void putToGroups(java.lang.String key, java.util.Set<java.lang.String> val) {
       if (this.groups == null) {
-        this.groups = new HashMap<String,Set<String>>();
+        this.groups = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>();
       }
       this.groups.put(key, val);
     }
 
-    public Map<String,Set<String>> getGroups() {
+    public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getGroups() {
       return this.groups;
     }
 
-    public setLocalityGroups_args setGroups(Map<String,Set<String>> groups) {
+    public setLocalityGroups_args setGroups(java.util.Map<java.lang.String,java.util.Set<java.lang.String>> groups) {
       this.groups = groups;
       return this;
     }
@@ -56793,13 +57492,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -56807,7 +57510,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -56815,14 +57518,14 @@
         if (value == null) {
           unsetGroups();
         } else {
-          setGroups((Map<String,Set<String>>)value);
+          setGroups((java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -56834,13 +57537,13 @@
         return getGroups();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -56851,11 +57554,11 @@
       case GROUPS:
         return isSetGroups();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof setLocalityGroups_args)
@@ -56866,6 +57569,8 @@
     public boolean equals(setLocalityGroups_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -56899,24 +57604,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_groups = true && (isSetGroups());
-      list.add(present_groups);
-      if (present_groups)
-        list.add(groups);
+      hashCode = hashCode * 8191 + ((isSetGroups()) ? 131071 : 524287);
+      if (isSetGroups())
+        hashCode = hashCode * 8191 + groups.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -56927,7 +57629,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -56937,7 +57639,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -56947,7 +57649,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetGroups()).compareTo(other.isSetGroups());
+      lastComparison = java.lang.Boolean.valueOf(isSetGroups()).compareTo(other.isSetGroups());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -56965,16 +57667,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("setLocalityGroups_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("setLocalityGroups_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -57017,7 +57719,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -57025,13 +57727,13 @@
       }
     }
 
-    private static class setLocalityGroups_argsStandardSchemeFactory implements SchemeFactory {
+    private static class setLocalityGroups_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setLocalityGroups_argsStandardScheme getScheme() {
         return new setLocalityGroups_argsStandardScheme();
       }
     }
 
-    private static class setLocalityGroups_argsStandardScheme extends StandardScheme<setLocalityGroups_args> {
+    private static class setLocalityGroups_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<setLocalityGroups_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, setLocalityGroups_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -57063,16 +57765,16 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map328 = iprot.readMapBegin();
-                  struct.groups = new HashMap<String,Set<String>>(2*_map328.size);
-                  String _key329;
-                  Set<String> _val330;
+                  struct.groups = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>(2*_map328.size);
+                  java.lang.String _key329;
+                  java.util.Set<java.lang.String> _val330;
                   for (int _i331 = 0; _i331 < _map328.size; ++_i331)
                   {
                     _key329 = iprot.readString();
                     {
                       org.apache.thrift.protocol.TSet _set332 = iprot.readSetBegin();
-                      _val330 = new HashSet<String>(2*_set332.size);
-                      String _elem333;
+                      _val330 = new java.util.HashSet<java.lang.String>(2*_set332.size);
+                      java.lang.String _elem333;
                       for (int _i334 = 0; _i334 < _set332.size; ++_i334)
                       {
                         _elem333 = iprot.readString();
@@ -57118,12 +57820,12 @@
           oprot.writeFieldBegin(GROUPS_FIELD_DESC);
           {
             oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, struct.groups.size()));
-            for (Map.Entry<String, Set<String>> _iter335 : struct.groups.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.util.Set<java.lang.String>> _iter335 : struct.groups.entrySet())
             {
               oprot.writeString(_iter335.getKey());
               {
                 oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, _iter335.getValue().size()));
-                for (String _iter336 : _iter335.getValue())
+                for (java.lang.String _iter336 : _iter335.getValue())
                 {
                   oprot.writeString(_iter336);
                 }
@@ -57140,18 +57842,18 @@
 
     }
 
-    private static class setLocalityGroups_argsTupleSchemeFactory implements SchemeFactory {
+    private static class setLocalityGroups_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setLocalityGroups_argsTupleScheme getScheme() {
         return new setLocalityGroups_argsTupleScheme();
       }
     }
 
-    private static class setLocalityGroups_argsTupleScheme extends TupleScheme<setLocalityGroups_args> {
+    private static class setLocalityGroups_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<setLocalityGroups_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, setLocalityGroups_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -57171,12 +57873,12 @@
         if (struct.isSetGroups()) {
           {
             oprot.writeI32(struct.groups.size());
-            for (Map.Entry<String, Set<String>> _iter337 : struct.groups.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.util.Set<java.lang.String>> _iter337 : struct.groups.entrySet())
             {
               oprot.writeString(_iter337.getKey());
               {
                 oprot.writeI32(_iter337.getValue().size());
-                for (String _iter338 : _iter337.getValue())
+                for (java.lang.String _iter338 : _iter337.getValue())
                 {
                   oprot.writeString(_iter338);
                 }
@@ -57188,8 +57890,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, setLocalityGroups_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -57201,16 +57903,16 @@
         if (incoming.get(2)) {
           {
             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);
-            String _key340;
-            Set<String> _val341;
+            struct.groups = new java.util.HashMap<java.lang.String,java.util.Set<java.lang.String>>(2*_map339.size);
+            java.lang.String _key340;
+            java.util.Set<java.lang.String> _val341;
             for (int _i342 = 0; _i342 < _map339.size; ++_i342)
             {
               _key340 = iprot.readString();
               {
                 org.apache.thrift.protocol.TSet _set343 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
-                _val341 = new HashSet<String>(2*_set343.size);
-                String _elem344;
+                _val341 = new java.util.HashSet<java.lang.String>(2*_set343.size);
+                java.lang.String _elem344;
                 for (int _i345 = 0; _i345 < _set343.size; ++_i345)
                 {
                   _elem344 = iprot.readString();
@@ -57225,6 +57927,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class setLocalityGroups_result implements org.apache.thrift.TBase<setLocalityGroups_result, setLocalityGroups_result._Fields>, java.io.Serializable, Cloneable, Comparable<setLocalityGroups_result>   {
@@ -57234,11 +57939,8 @@
     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 setLocalityGroups_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new setLocalityGroups_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new setLocalityGroups_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new setLocalityGroups_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -57250,10 +57952,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -57280,21 +57982,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -57303,22 +58005,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setLocalityGroups_result.class, metaDataMap);
     }
 
@@ -57434,7 +58136,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -57463,7 +58165,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -57475,13 +58177,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -57492,11 +58194,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof setLocalityGroups_result)
@@ -57507,6 +58209,8 @@
     public boolean equals(setLocalityGroups_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -57540,24 +58244,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -57568,7 +58269,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -57578,7 +58279,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -57588,7 +58289,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -57606,16 +58307,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("setLocalityGroups_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("setLocalityGroups_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -57658,7 +58359,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -57666,13 +58367,13 @@
       }
     }
 
-    private static class setLocalityGroups_resultStandardSchemeFactory implements SchemeFactory {
+    private static class setLocalityGroups_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setLocalityGroups_resultStandardScheme getScheme() {
         return new setLocalityGroups_resultStandardScheme();
       }
     }
 
-    private static class setLocalityGroups_resultStandardScheme extends StandardScheme<setLocalityGroups_result> {
+    private static class setLocalityGroups_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<setLocalityGroups_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, setLocalityGroups_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -57747,18 +58448,18 @@
 
     }
 
-    private static class setLocalityGroups_resultTupleSchemeFactory implements SchemeFactory {
+    private static class setLocalityGroups_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setLocalityGroups_resultTupleScheme getScheme() {
         return new setLocalityGroups_resultTupleScheme();
       }
     }
 
-    private static class setLocalityGroups_resultTupleScheme extends TupleScheme<setLocalityGroups_result> {
+    private static class setLocalityGroups_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<setLocalityGroups_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, setLocalityGroups_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -57782,8 +58483,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, setLocalityGroups_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -57802,6 +58503,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class setTableProperty_args implements org.apache.thrift.TBase<setTableProperty_args, setTableProperty_args._Fields>, java.io.Serializable, Cloneable, Comparable<setTableProperty_args>   {
@@ -57812,16 +58516,13 @@
     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 setTableProperty_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new setTableProperty_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new setTableProperty_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new setTableProperty_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public String property; // required
-    public String value; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.lang.String property; // required
+    public java.lang.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 {
@@ -57830,10 +58531,10 @@
       PROPERTY((short)3, "property"),
       VALUE((short)4, "value");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -57862,21 +58563,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -57885,15 +58586,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -57902,7 +58603,7 @@
           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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setTableProperty_args.class, metaDataMap);
     }
 
@@ -57910,10 +58611,10 @@
     }
 
     public setTableProperty_args(
-      ByteBuffer login,
-      String tableName,
-      String property,
-      String value)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.lang.String property,
+      java.lang.String value)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -57957,16 +58658,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public setTableProperty_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public setTableProperty_args setLogin(ByteBuffer login) {
+    public setTableProperty_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -57986,11 +58687,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public setTableProperty_args setTableName(String tableName) {
+    public setTableProperty_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -58010,11 +58711,11 @@
       }
     }
 
-    public String getProperty() {
+    public java.lang.String getProperty() {
       return this.property;
     }
 
-    public setTableProperty_args setProperty(String property) {
+    public setTableProperty_args setProperty(java.lang.String property) {
       this.property = property;
       return this;
     }
@@ -58034,11 +58735,11 @@
       }
     }
 
-    public String getValue() {
+    public java.lang.String getValue() {
       return this.value;
     }
 
-    public setTableProperty_args setValue(String value) {
+    public setTableProperty_args setValue(java.lang.String value) {
       this.value = value;
       return this;
     }
@@ -58058,13 +58759,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -58072,7 +58777,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -58080,7 +58785,7 @@
         if (value == null) {
           unsetProperty();
         } else {
-          setProperty((String)value);
+          setProperty((java.lang.String)value);
         }
         break;
 
@@ -58088,14 +58793,14 @@
         if (value == null) {
           unsetValue();
         } else {
-          setValue((String)value);
+          setValue((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -58110,13 +58815,13 @@
         return getValue();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -58129,11 +58834,11 @@
       case VALUE:
         return isSetValue();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof setTableProperty_args)
@@ -58144,6 +58849,8 @@
     public boolean equals(setTableProperty_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -58186,29 +58893,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_property = true && (isSetProperty());
-      list.add(present_property);
-      if (present_property)
-        list.add(property);
+      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
+      if (isSetProperty())
+        hashCode = hashCode * 8191 + property.hashCode();
 
-      boolean present_value = true && (isSetValue());
-      list.add(present_value);
-      if (present_value)
-        list.add(value);
+      hashCode = hashCode * 8191 + ((isSetValue()) ? 131071 : 524287);
+      if (isSetValue())
+        hashCode = hashCode * 8191 + value.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -58219,7 +58922,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -58229,7 +58932,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -58239,7 +58942,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
+      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -58249,7 +58952,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
+      lastComparison = java.lang.Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -58267,16 +58970,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("setTableProperty_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("setTableProperty_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -58327,7 +59030,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -58335,13 +59038,13 @@
       }
     }
 
-    private static class setTableProperty_argsStandardSchemeFactory implements SchemeFactory {
+    private static class setTableProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setTableProperty_argsStandardScheme getScheme() {
         return new setTableProperty_argsStandardScheme();
       }
     }
 
-    private static class setTableProperty_argsStandardScheme extends StandardScheme<setTableProperty_args> {
+    private static class setTableProperty_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<setTableProperty_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, setTableProperty_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -58426,18 +59129,18 @@
 
     }
 
-    private static class setTableProperty_argsTupleSchemeFactory implements SchemeFactory {
+    private static class setTableProperty_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setTableProperty_argsTupleScheme getScheme() {
         return new setTableProperty_argsTupleScheme();
       }
     }
 
-    private static class setTableProperty_argsTupleScheme extends TupleScheme<setTableProperty_args> {
+    private static class setTableProperty_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<setTableProperty_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, setTableProperty_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -58467,8 +59170,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, setTableProperty_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -58488,6 +59191,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class setTableProperty_result implements org.apache.thrift.TBase<setTableProperty_result, setTableProperty_result._Fields>, java.io.Serializable, Cloneable, Comparable<setTableProperty_result>   {
@@ -58497,11 +59203,8 @@
     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 setTableProperty_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new setTableProperty_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new setTableProperty_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new setTableProperty_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -58513,10 +59216,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -58543,21 +59246,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -58566,22 +59269,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setTableProperty_result.class, metaDataMap);
     }
 
@@ -58697,7 +59400,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -58726,7 +59429,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -58738,13 +59441,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -58755,11 +59458,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof setTableProperty_result)
@@ -58770,6 +59473,8 @@
     public boolean equals(setTableProperty_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -58803,24 +59508,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -58831,7 +59533,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -58841,7 +59543,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -58851,7 +59553,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -58869,16 +59571,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("setTableProperty_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("setTableProperty_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -58921,7 +59623,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -58929,13 +59631,13 @@
       }
     }
 
-    private static class setTableProperty_resultStandardSchemeFactory implements SchemeFactory {
+    private static class setTableProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setTableProperty_resultStandardScheme getScheme() {
         return new setTableProperty_resultStandardScheme();
       }
     }
 
-    private static class setTableProperty_resultStandardScheme extends StandardScheme<setTableProperty_result> {
+    private static class setTableProperty_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<setTableProperty_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, setTableProperty_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -59010,18 +59712,18 @@
 
     }
 
-    private static class setTableProperty_resultTupleSchemeFactory implements SchemeFactory {
+    private static class setTableProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setTableProperty_resultTupleScheme getScheme() {
         return new setTableProperty_resultTupleScheme();
       }
     }
 
-    private static class setTableProperty_resultTupleScheme extends TupleScheme<setTableProperty_result> {
+    private static class setTableProperty_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<setTableProperty_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, setTableProperty_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -59045,8 +59747,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, setTableProperty_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -59065,6 +59767,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class splitRangeByTablets_args implements org.apache.thrift.TBase<splitRangeByTablets_args, splitRangeByTablets_args._Fields>, java.io.Serializable, Cloneable, Comparable<splitRangeByTablets_args>   {
@@ -59075,14 +59780,11 @@
     private static final org.apache.thrift.protocol.TField RANGE_FIELD_DESC = new org.apache.thrift.protocol.TField("range", org.apache.thrift.protocol.TType.STRUCT, (short)3);
     private static final org.apache.thrift.protocol.TField MAX_SPLITS_FIELD_DESC = new org.apache.thrift.protocol.TField("maxSplits", 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 splitRangeByTablets_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new splitRangeByTablets_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new splitRangeByTablets_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new splitRangeByTablets_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public Range range; // required
     public int maxSplits; // required
 
@@ -59093,10 +59795,10 @@
       RANGE((short)3, "range"),
       MAX_SPLITS((short)4, "maxSplits");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -59125,21 +59827,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -59148,7 +59850,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -59156,9 +59858,9 @@
     // isset id assignments
     private static final int __MAXSPLITS_ISSET_ID = 0;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -59167,7 +59869,7 @@
           new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Range.class)));
       tmpMap.put(_Fields.MAX_SPLITS, new org.apache.thrift.meta_data.FieldMetaData("maxSplits", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(splitRangeByTablets_args.class, metaDataMap);
     }
 
@@ -59175,8 +59877,8 @@
     }
 
     public splitRangeByTablets_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       Range range,
       int maxSplits)
     {
@@ -59223,16 +59925,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public splitRangeByTablets_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public splitRangeByTablets_args setLogin(ByteBuffer login) {
+    public splitRangeByTablets_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -59252,11 +59954,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public splitRangeByTablets_args setTableName(String tableName) {
+    public splitRangeByTablets_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -59311,25 +60013,29 @@
     }
 
     public void unsetMaxSplits() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __MAXSPLITS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __MAXSPLITS_ISSET_ID);
     }
 
     /** Returns true if field maxSplits is set (has been assigned a value) and false otherwise */
     public boolean isSetMaxSplits() {
-      return EncodingUtils.testBit(__isset_bitfield, __MAXSPLITS_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __MAXSPLITS_ISSET_ID);
     }
 
     public void setMaxSplitsIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __MAXSPLITS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __MAXSPLITS_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -59337,7 +60043,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -59353,14 +60059,14 @@
         if (value == null) {
           unsetMaxSplits();
         } else {
-          setMaxSplits((Integer)value);
+          setMaxSplits((java.lang.Integer)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -59375,13 +60081,13 @@
         return getMaxSplits();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -59394,11 +60100,11 @@
       case MAX_SPLITS:
         return isSetMaxSplits();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof splitRangeByTablets_args)
@@ -59409,6 +60115,8 @@
     public boolean equals(splitRangeByTablets_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -59451,29 +60159,23 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_range = true && (isSetRange());
-      list.add(present_range);
-      if (present_range)
-        list.add(range);
+      hashCode = hashCode * 8191 + ((isSetRange()) ? 131071 : 524287);
+      if (isSetRange())
+        hashCode = hashCode * 8191 + range.hashCode();
 
-      boolean present_maxSplits = true;
-      list.add(present_maxSplits);
-      if (present_maxSplits)
-        list.add(maxSplits);
+      hashCode = hashCode * 8191 + maxSplits;
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -59484,7 +60186,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -59494,7 +60196,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -59504,7 +60206,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetRange()).compareTo(other.isSetRange());
+      lastComparison = java.lang.Boolean.valueOf(isSetRange()).compareTo(other.isSetRange());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -59514,7 +60216,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetMaxSplits()).compareTo(other.isSetMaxSplits());
+      lastComparison = java.lang.Boolean.valueOf(isSetMaxSplits()).compareTo(other.isSetMaxSplits());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -59532,16 +60234,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("splitRangeByTablets_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("splitRangeByTablets_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -59591,7 +60293,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -59601,13 +60303,13 @@
       }
     }
 
-    private static class splitRangeByTablets_argsStandardSchemeFactory implements SchemeFactory {
+    private static class splitRangeByTablets_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public splitRangeByTablets_argsStandardScheme getScheme() {
         return new splitRangeByTablets_argsStandardScheme();
       }
     }
 
-    private static class splitRangeByTablets_argsStandardScheme extends StandardScheme<splitRangeByTablets_args> {
+    private static class splitRangeByTablets_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<splitRangeByTablets_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, splitRangeByTablets_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -59691,18 +60393,18 @@
 
     }
 
-    private static class splitRangeByTablets_argsTupleSchemeFactory implements SchemeFactory {
+    private static class splitRangeByTablets_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public splitRangeByTablets_argsTupleScheme getScheme() {
         return new splitRangeByTablets_argsTupleScheme();
       }
     }
 
-    private static class splitRangeByTablets_argsTupleScheme extends TupleScheme<splitRangeByTablets_args> {
+    private static class splitRangeByTablets_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<splitRangeByTablets_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, splitRangeByTablets_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -59732,8 +60434,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, splitRangeByTablets_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -59754,6 +60456,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class splitRangeByTablets_result implements org.apache.thrift.TBase<splitRangeByTablets_result, splitRangeByTablets_result._Fields>, java.io.Serializable, Cloneable, Comparable<splitRangeByTablets_result>   {
@@ -59764,13 +60469,10 @@
     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 splitRangeByTablets_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new splitRangeByTablets_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new splitRangeByTablets_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new splitRangeByTablets_resultTupleSchemeFactory();
 
-    public Set<Range> success; // required
+    public java.util.Set<Range> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -59782,10 +60484,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -59814,21 +60516,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -59837,25 +60539,25 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.SetMetaData(org.apache.thrift.protocol.TType.SET, 
               new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Range.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(splitRangeByTablets_result.class, metaDataMap);
     }
 
@@ -59863,7 +60565,7 @@
     }
 
     public splitRangeByTablets_result(
-      Set<Range> success,
+      java.util.Set<Range> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -59880,7 +60582,7 @@
      */
     public splitRangeByTablets_result(splitRangeByTablets_result other) {
       if (other.isSetSuccess()) {
-        Set<Range> __this__success = new HashSet<Range>(other.success.size());
+        java.util.Set<Range> __this__success = new java.util.HashSet<Range>(other.success.size());
         for (Range other_element : other.success) {
           __this__success.add(new Range(other_element));
         }
@@ -59919,16 +60621,16 @@
 
     public void addToSuccess(Range elem) {
       if (this.success == null) {
-        this.success = new HashSet<Range>();
+        this.success = new java.util.HashSet<Range>();
       }
       this.success.add(elem);
     }
 
-    public Set<Range> getSuccess() {
+    public java.util.Set<Range> getSuccess() {
       return this.success;
     }
 
-    public splitRangeByTablets_result setSuccess(Set<Range> success) {
+    public splitRangeByTablets_result setSuccess(java.util.Set<Range> success) {
       this.success = success;
       return this;
     }
@@ -60020,13 +60722,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Set<Range>)value);
+          setSuccess((java.util.Set<Range>)value);
         }
         break;
 
@@ -60057,7 +60759,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -60072,13 +60774,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -60091,11 +60793,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof splitRangeByTablets_result)
@@ -60106,6 +60808,8 @@
     public boolean equals(splitRangeByTablets_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -60148,29 +60852,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -60181,7 +60881,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -60191,7 +60891,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -60201,7 +60901,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -60211,7 +60911,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -60229,16 +60929,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("splitRangeByTablets_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("splitRangeByTablets_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -60289,7 +60989,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -60297,13 +60997,13 @@
       }
     }
 
-    private static class splitRangeByTablets_resultStandardSchemeFactory implements SchemeFactory {
+    private static class splitRangeByTablets_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public splitRangeByTablets_resultStandardScheme getScheme() {
         return new splitRangeByTablets_resultStandardScheme();
       }
     }
 
-    private static class splitRangeByTablets_resultStandardScheme extends StandardScheme<splitRangeByTablets_result> {
+    private static class splitRangeByTablets_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<splitRangeByTablets_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, splitRangeByTablets_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -60319,7 +61019,7 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set346 = iprot.readSetBegin();
-                  struct.success = new HashSet<Range>(2*_set346.size);
+                  struct.success = new java.util.HashSet<Range>(2*_set346.size);
                   Range _elem347;
                   for (int _i348 = 0; _i348 < _set346.size; ++_i348)
                   {
@@ -60409,18 +61109,18 @@
 
     }
 
-    private static class splitRangeByTablets_resultTupleSchemeFactory implements SchemeFactory {
+    private static class splitRangeByTablets_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public splitRangeByTablets_resultTupleScheme getScheme() {
         return new splitRangeByTablets_resultTupleScheme();
       }
     }
 
-    private static class splitRangeByTablets_resultTupleScheme extends TupleScheme<splitRangeByTablets_result> {
+    private static class splitRangeByTablets_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<splitRangeByTablets_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, splitRangeByTablets_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -60456,12 +61156,12 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, splitRangeByTablets_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           {
             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);
+            struct.success = new java.util.HashSet<Range>(2*_set351.size);
             Range _elem352;
             for (int _i353 = 0; _i353 < _set351.size; ++_i353)
             {
@@ -60490,6 +61190,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class tableExists_args implements org.apache.thrift.TBase<tableExists_args, tableExists_args._Fields>, java.io.Serializable, Cloneable, Comparable<tableExists_args>   {
@@ -60498,24 +61201,21 @@
     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 TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", 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 tableExists_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new tableExists_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new tableExists_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new tableExists_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // 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"),
       TABLE_NAME((short)2, "tableName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -60540,21 +61240,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -60563,20 +61263,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(tableExists_args.class, metaDataMap);
     }
 
@@ -60584,8 +61284,8 @@
     }
 
     public tableExists_args(
-      ByteBuffer login,
-      String tableName)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -60619,16 +61319,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public tableExists_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public tableExists_args setLogin(ByteBuffer login) {
+    public tableExists_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -60648,11 +61348,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public tableExists_args setTableName(String tableName) {
+    public tableExists_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -60672,13 +61372,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -60686,14 +61390,14 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -60702,13 +61406,13 @@
         return getTableName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -60717,11 +61421,11 @@
       case TABLE_NAME:
         return isSetTableName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof tableExists_args)
@@ -60732,6 +61436,8 @@
     public boolean equals(tableExists_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -60756,19 +61462,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -60779,7 +61483,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -60789,7 +61493,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -60807,16 +61511,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("tableExists_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("tableExists_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -60851,7 +61555,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -60859,13 +61563,13 @@
       }
     }
 
-    private static class tableExists_argsStandardSchemeFactory implements SchemeFactory {
+    private static class tableExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public tableExists_argsStandardScheme getScheme() {
         return new tableExists_argsStandardScheme();
       }
     }
 
-    private static class tableExists_argsStandardScheme extends StandardScheme<tableExists_args> {
+    private static class tableExists_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<tableExists_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, tableExists_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -60924,18 +61628,18 @@
 
     }
 
-    private static class tableExists_argsTupleSchemeFactory implements SchemeFactory {
+    private static class tableExists_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public tableExists_argsTupleScheme getScheme() {
         return new tableExists_argsTupleScheme();
       }
     }
 
-    private static class tableExists_argsTupleScheme extends TupleScheme<tableExists_args> {
+    private static class tableExists_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<tableExists_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, tableExists_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -60953,8 +61657,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, tableExists_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -60966,6 +61670,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class tableExists_result implements org.apache.thrift.TBase<tableExists_result, tableExists_result._Fields>, java.io.Serializable, Cloneable, Comparable<tableExists_result>   {
@@ -60973,11 +61680,8 @@
 
     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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new tableExists_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new tableExists_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new tableExists_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new tableExists_resultTupleSchemeFactory();
 
     public boolean success; // required
 
@@ -60985,10 +61689,10 @@
     public enum _Fields implements org.apache.thrift.TFieldIdEnum {
       SUCCESS((short)0, "success");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -61011,21 +61715,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -61034,7 +61738,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -61042,12 +61746,12 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(tableExists_result.class, metaDataMap);
     }
 
@@ -61091,55 +61795,55 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Boolean)value);
+          setSuccess((java.lang.Boolean)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return isSuccess();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SUCCESS:
         return isSetSuccess();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof tableExists_result)
@@ -61150,6 +61854,8 @@
     public boolean equals(tableExists_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -61165,14 +61871,11 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -61183,7 +61886,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -61201,16 +61904,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("tableExists_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("tableExists_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -61233,7 +61936,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -61243,13 +61946,13 @@
       }
     }
 
-    private static class tableExists_resultStandardSchemeFactory implements SchemeFactory {
+    private static class tableExists_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public tableExists_resultStandardScheme getScheme() {
         return new tableExists_resultStandardScheme();
       }
     }
 
-    private static class tableExists_resultStandardScheme extends StandardScheme<tableExists_result> {
+    private static class tableExists_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<tableExists_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, tableExists_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -61295,18 +61998,18 @@
 
     }
 
-    private static class tableExists_resultTupleSchemeFactory implements SchemeFactory {
+    private static class tableExists_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public tableExists_resultTupleScheme getScheme() {
         return new tableExists_resultTupleScheme();
       }
     }
 
-    private static class tableExists_resultTupleScheme extends TupleScheme<tableExists_result> {
+    private static class tableExists_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<tableExists_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, tableExists_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -61318,8 +62021,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, tableExists_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.success = iprot.readBool();
           struct.setSuccessIsSet(true);
@@ -61327,6 +62030,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class tableIdMap_args implements org.apache.thrift.TBase<tableIdMap_args, tableIdMap_args._Fields>, java.io.Serializable, Cloneable, Comparable<tableIdMap_args>   {
@@ -61334,22 +62040,19 @@
 
     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 tableIdMap_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new tableIdMap_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new tableIdMap_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new tableIdMap_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
+    public java.nio.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -61372,21 +62075,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -61395,18 +62098,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(tableIdMap_args.class, metaDataMap);
     }
 
@@ -61414,7 +62117,7 @@
     }
 
     public tableIdMap_args(
-      ByteBuffer login)
+      java.nio.ByteBuffer login)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -61443,16 +62146,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public tableIdMap_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public tableIdMap_args setLogin(ByteBuffer login) {
+    public tableIdMap_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -61472,43 +62175,47 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case LOGIN:
         return isSetLogin();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof tableIdMap_args)
@@ -61519,6 +62226,8 @@
     public boolean equals(tableIdMap_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -61534,14 +62243,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -61552,7 +62260,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -61570,16 +62278,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("tableIdMap_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("tableIdMap_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -61606,7 +62314,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -61614,13 +62322,13 @@
       }
     }
 
-    private static class tableIdMap_argsStandardSchemeFactory implements SchemeFactory {
+    private static class tableIdMap_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public tableIdMap_argsStandardScheme getScheme() {
         return new tableIdMap_argsStandardScheme();
       }
     }
 
-    private static class tableIdMap_argsStandardScheme extends StandardScheme<tableIdMap_args> {
+    private static class tableIdMap_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<tableIdMap_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, tableIdMap_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -61666,18 +62374,18 @@
 
     }
 
-    private static class tableIdMap_argsTupleSchemeFactory implements SchemeFactory {
+    private static class tableIdMap_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public tableIdMap_argsTupleScheme getScheme() {
         return new tableIdMap_argsTupleScheme();
       }
     }
 
-    private static class tableIdMap_argsTupleScheme extends TupleScheme<tableIdMap_args> {
+    private static class tableIdMap_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<tableIdMap_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, tableIdMap_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -61689,8 +62397,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, tableIdMap_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -61698,6 +62406,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class tableIdMap_result implements org.apache.thrift.TBase<tableIdMap_result, tableIdMap_result._Fields>, java.io.Serializable, Cloneable, Comparable<tableIdMap_result>   {
@@ -61705,22 +62416,19 @@
 
     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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new tableIdMap_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new tableIdMap_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new tableIdMap_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new tableIdMap_resultTupleSchemeFactory();
 
-    public Map<String,String> success; // required
+    public java.util.Map<java.lang.String,java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -61743,21 +62451,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -61766,20 +62474,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(tableIdMap_result.class, metaDataMap);
     }
 
@@ -61787,7 +62495,7 @@
     }
 
     public tableIdMap_result(
-      Map<String,String> success)
+      java.util.Map<java.lang.String,java.lang.String> success)
     {
       this();
       this.success = success;
@@ -61798,7 +62506,7 @@
      */
     public tableIdMap_result(tableIdMap_result other) {
       if (other.isSetSuccess()) {
-        Map<String,String> __this__success = new HashMap<String,String>(other.success);
+        java.util.Map<java.lang.String,java.lang.String> __this__success = new java.util.HashMap<java.lang.String,java.lang.String>(other.success);
         this.success = __this__success;
       }
     }
@@ -61816,18 +62524,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, String val) {
+    public void putToSuccess(java.lang.String key, java.lang.String val) {
       if (this.success == null) {
-        this.success = new HashMap<String,String>();
+        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,String> getSuccess() {
+    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
       return this.success;
     }
 
-    public tableIdMap_result setSuccess(Map<String,String> success) {
+    public tableIdMap_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
       this.success = success;
       return this;
     }
@@ -61847,43 +62555,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,String>)value);
+          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SUCCESS:
         return isSetSuccess();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof tableIdMap_result)
@@ -61894,6 +62602,8 @@
     public boolean equals(tableIdMap_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -61909,14 +62619,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -61927,7 +62636,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -61945,16 +62654,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("tableIdMap_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("tableIdMap_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -61981,7 +62690,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -61989,13 +62698,13 @@
       }
     }
 
-    private static class tableIdMap_resultStandardSchemeFactory implements SchemeFactory {
+    private static class tableIdMap_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public tableIdMap_resultStandardScheme getScheme() {
         return new tableIdMap_resultStandardScheme();
       }
     }
 
-    private static class tableIdMap_resultStandardScheme extends StandardScheme<tableIdMap_result> {
+    private static class tableIdMap_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<tableIdMap_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, tableIdMap_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -62011,9 +62720,9 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map354 = iprot.readMapBegin();
-                  struct.success = new HashMap<String,String>(2*_map354.size);
-                  String _key355;
-                  String _val356;
+                  struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map354.size);
+                  java.lang.String _key355;
+                  java.lang.String _val356;
                   for (int _i357 = 0; _i357 < _map354.size; ++_i357)
                   {
                     _key355 = iprot.readString();
@@ -62046,7 +62755,7 @@
           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> _iter358 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter358 : struct.success.entrySet())
             {
               oprot.writeString(_iter358.getKey());
               oprot.writeString(_iter358.getValue());
@@ -62061,18 +62770,18 @@
 
     }
 
-    private static class tableIdMap_resultTupleSchemeFactory implements SchemeFactory {
+    private static class tableIdMap_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public tableIdMap_resultTupleScheme getScheme() {
         return new tableIdMap_resultTupleScheme();
       }
     }
 
-    private static class tableIdMap_resultTupleScheme extends TupleScheme<tableIdMap_result> {
+    private static class tableIdMap_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<tableIdMap_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, tableIdMap_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -62080,7 +62789,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, String> _iter359 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter359 : struct.success.entrySet())
             {
               oprot.writeString(_iter359.getKey());
               oprot.writeString(_iter359.getValue());
@@ -62091,14 +62800,14 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, tableIdMap_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           {
             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);
-            String _key361;
-            String _val362;
+            struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map360.size);
+            java.lang.String _key361;
+            java.lang.String _val362;
             for (int _i363 = 0; _i363 < _map360.size; ++_i363)
             {
               _key361 = iprot.readString();
@@ -62111,6 +62820,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class testTableClassLoad_args implements org.apache.thrift.TBase<testTableClassLoad_args, testTableClassLoad_args._Fields>, java.io.Serializable, Cloneable, Comparable<testTableClassLoad_args>   {
@@ -62121,16 +62833,13 @@
     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 testTableClassLoad_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new testTableClassLoad_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new testTableClassLoad_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new testTableClassLoad_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public String className; // required
-    public String asTypeName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.lang.String className; // required
+    public java.lang.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 {
@@ -62139,10 +62848,10 @@
       CLASS_NAME((short)3, "className"),
       AS_TYPE_NAME((short)4, "asTypeName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -62171,21 +62880,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -62194,15 +62903,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -62211,7 +62920,7 @@
           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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testTableClassLoad_args.class, metaDataMap);
     }
 
@@ -62219,10 +62928,10 @@
     }
 
     public testTableClassLoad_args(
-      ByteBuffer login,
-      String tableName,
-      String className,
-      String asTypeName)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.lang.String className,
+      java.lang.String asTypeName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -62266,16 +62975,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public testTableClassLoad_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public testTableClassLoad_args setLogin(ByteBuffer login) {
+    public testTableClassLoad_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -62295,11 +63004,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public testTableClassLoad_args setTableName(String tableName) {
+    public testTableClassLoad_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -62319,11 +63028,11 @@
       }
     }
 
-    public String getClassName() {
+    public java.lang.String getClassName() {
       return this.className;
     }
 
-    public testTableClassLoad_args setClassName(String className) {
+    public testTableClassLoad_args setClassName(java.lang.String className) {
       this.className = className;
       return this;
     }
@@ -62343,11 +63052,11 @@
       }
     }
 
-    public String getAsTypeName() {
+    public java.lang.String getAsTypeName() {
       return this.asTypeName;
     }
 
-    public testTableClassLoad_args setAsTypeName(String asTypeName) {
+    public testTableClassLoad_args setAsTypeName(java.lang.String asTypeName) {
       this.asTypeName = asTypeName;
       return this;
     }
@@ -62367,13 +63076,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -62381,7 +63094,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -62389,7 +63102,7 @@
         if (value == null) {
           unsetClassName();
         } else {
-          setClassName((String)value);
+          setClassName((java.lang.String)value);
         }
         break;
 
@@ -62397,14 +63110,14 @@
         if (value == null) {
           unsetAsTypeName();
         } else {
-          setAsTypeName((String)value);
+          setAsTypeName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -62419,13 +63132,13 @@
         return getAsTypeName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -62438,11 +63151,11 @@
       case AS_TYPE_NAME:
         return isSetAsTypeName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof testTableClassLoad_args)
@@ -62453,6 +63166,8 @@
     public boolean equals(testTableClassLoad_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -62495,29 +63210,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_className = true && (isSetClassName());
-      list.add(present_className);
-      if (present_className)
-        list.add(className);
+      hashCode = hashCode * 8191 + ((isSetClassName()) ? 131071 : 524287);
+      if (isSetClassName())
+        hashCode = hashCode * 8191 + className.hashCode();
 
-      boolean present_asTypeName = true && (isSetAsTypeName());
-      list.add(present_asTypeName);
-      if (present_asTypeName)
-        list.add(asTypeName);
+      hashCode = hashCode * 8191 + ((isSetAsTypeName()) ? 131071 : 524287);
+      if (isSetAsTypeName())
+        hashCode = hashCode * 8191 + asTypeName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -62528,7 +63239,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -62538,7 +63249,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -62548,7 +63259,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
+      lastComparison = java.lang.Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -62558,7 +63269,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetAsTypeName()).compareTo(other.isSetAsTypeName());
+      lastComparison = java.lang.Boolean.valueOf(isSetAsTypeName()).compareTo(other.isSetAsTypeName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -62576,16 +63287,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("testTableClassLoad_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("testTableClassLoad_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -62636,7 +63347,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -62644,13 +63355,13 @@
       }
     }
 
-    private static class testTableClassLoad_argsStandardSchemeFactory implements SchemeFactory {
+    private static class testTableClassLoad_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testTableClassLoad_argsStandardScheme getScheme() {
         return new testTableClassLoad_argsStandardScheme();
       }
     }
 
-    private static class testTableClassLoad_argsStandardScheme extends StandardScheme<testTableClassLoad_args> {
+    private static class testTableClassLoad_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<testTableClassLoad_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, testTableClassLoad_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -62735,18 +63446,18 @@
 
     }
 
-    private static class testTableClassLoad_argsTupleSchemeFactory implements SchemeFactory {
+    private static class testTableClassLoad_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testTableClassLoad_argsTupleScheme getScheme() {
         return new testTableClassLoad_argsTupleScheme();
       }
     }
 
-    private static class testTableClassLoad_argsTupleScheme extends TupleScheme<testTableClassLoad_args> {
+    private static class testTableClassLoad_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<testTableClassLoad_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, testTableClassLoad_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -62776,8 +63487,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, testTableClassLoad_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -62797,6 +63508,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class testTableClassLoad_result implements org.apache.thrift.TBase<testTableClassLoad_result, testTableClassLoad_result._Fields>, java.io.Serializable, Cloneable, Comparable<testTableClassLoad_result>   {
@@ -62807,11 +63521,8 @@
     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 testTableClassLoad_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new testTableClassLoad_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new testTableClassLoad_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new testTableClassLoad_resultTupleSchemeFactory();
 
     public boolean success; // required
     public AccumuloException ouch1; // required
@@ -62825,10 +63536,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -62857,21 +63568,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -62880,7 +63591,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -62888,18 +63599,18 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testTableClassLoad_result.class, metaDataMap);
     }
 
@@ -62961,16 +63672,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public AccumuloException getOuch1() {
@@ -63045,13 +63756,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Boolean)value);
+          setSuccess((java.lang.Boolean)value);
         }
         break;
 
@@ -63082,7 +63793,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return isSuccess();
@@ -63097,13 +63808,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -63116,11 +63827,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof testTableClassLoad_result)
@@ -63131,6 +63842,8 @@
     public boolean equals(testTableClassLoad_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -63173,29 +63886,23 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -63206,7 +63913,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -63216,7 +63923,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -63226,7 +63933,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -63236,7 +63943,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -63254,16 +63961,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("testTableClassLoad_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("testTableClassLoad_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -63310,7 +64017,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -63320,13 +64027,13 @@
       }
     }
 
-    private static class testTableClassLoad_resultStandardSchemeFactory implements SchemeFactory {
+    private static class testTableClassLoad_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testTableClassLoad_resultStandardScheme getScheme() {
         return new testTableClassLoad_resultStandardScheme();
       }
     }
 
-    private static class testTableClassLoad_resultStandardScheme extends StandardScheme<testTableClassLoad_result> {
+    private static class testTableClassLoad_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<testTableClassLoad_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, testTableClassLoad_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -63414,18 +64121,18 @@
 
     }
 
-    private static class testTableClassLoad_resultTupleSchemeFactory implements SchemeFactory {
+    private static class testTableClassLoad_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testTableClassLoad_resultTupleScheme getScheme() {
         return new testTableClassLoad_resultTupleScheme();
       }
     }
 
-    private static class testTableClassLoad_resultTupleScheme extends TupleScheme<testTableClassLoad_result> {
+    private static class testTableClassLoad_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<testTableClassLoad_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, testTableClassLoad_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -63455,8 +64162,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, testTableClassLoad_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = iprot.readBool();
           struct.setSuccessIsSet(true);
@@ -63479,6 +64186,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class pingTabletServer_args implements org.apache.thrift.TBase<pingTabletServer_args, pingTabletServer_args._Fields>, java.io.Serializable, Cloneable, Comparable<pingTabletServer_args>   {
@@ -63487,24 +64197,21 @@
     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 TSERVER_FIELD_DESC = new org.apache.thrift.protocol.TField("tserver", 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 pingTabletServer_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new pingTabletServer_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pingTabletServer_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pingTabletServer_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tserver; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tserver; // 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"),
       TSERVER((short)2, "tserver");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -63529,21 +64236,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -63552,20 +64259,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TSERVER, new org.apache.thrift.meta_data.FieldMetaData("tserver", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pingTabletServer_args.class, metaDataMap);
     }
 
@@ -63573,8 +64280,8 @@
     }
 
     public pingTabletServer_args(
-      ByteBuffer login,
-      String tserver)
+      java.nio.ByteBuffer login,
+      java.lang.String tserver)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -63608,16 +64315,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public pingTabletServer_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public pingTabletServer_args setLogin(ByteBuffer login) {
+    public pingTabletServer_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -63637,11 +64344,11 @@
       }
     }
 
-    public String getTserver() {
+    public java.lang.String getTserver() {
       return this.tserver;
     }
 
-    public pingTabletServer_args setTserver(String tserver) {
+    public pingTabletServer_args setTserver(java.lang.String tserver) {
       this.tserver = tserver;
       return this;
     }
@@ -63661,13 +64368,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -63675,14 +64386,14 @@
         if (value == null) {
           unsetTserver();
         } else {
-          setTserver((String)value);
+          setTserver((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -63691,13 +64402,13 @@
         return getTserver();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -63706,11 +64417,11 @@
       case TSERVER:
         return isSetTserver();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof pingTabletServer_args)
@@ -63721,6 +64432,8 @@
     public boolean equals(pingTabletServer_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -63745,19 +64458,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tserver = true && (isSetTserver());
-      list.add(present_tserver);
-      if (present_tserver)
-        list.add(tserver);
+      hashCode = hashCode * 8191 + ((isSetTserver()) ? 131071 : 524287);
+      if (isSetTserver())
+        hashCode = hashCode * 8191 + tserver.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -63768,7 +64479,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -63778,7 +64489,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTserver()).compareTo(other.isSetTserver());
+      lastComparison = java.lang.Boolean.valueOf(isSetTserver()).compareTo(other.isSetTserver());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -63796,16 +64507,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("pingTabletServer_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pingTabletServer_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -63840,7 +64551,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -63848,13 +64559,13 @@
       }
     }
 
-    private static class pingTabletServer_argsStandardSchemeFactory implements SchemeFactory {
+    private static class pingTabletServer_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public pingTabletServer_argsStandardScheme getScheme() {
         return new pingTabletServer_argsStandardScheme();
       }
     }
 
-    private static class pingTabletServer_argsStandardScheme extends StandardScheme<pingTabletServer_args> {
+    private static class pingTabletServer_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pingTabletServer_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, pingTabletServer_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -63913,18 +64624,18 @@
 
     }
 
-    private static class pingTabletServer_argsTupleSchemeFactory implements SchemeFactory {
+    private static class pingTabletServer_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public pingTabletServer_argsTupleScheme getScheme() {
         return new pingTabletServer_argsTupleScheme();
       }
     }
 
-    private static class pingTabletServer_argsTupleScheme extends TupleScheme<pingTabletServer_args> {
+    private static class pingTabletServer_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pingTabletServer_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, pingTabletServer_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -63942,8 +64653,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, pingTabletServer_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -63955,6 +64666,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class pingTabletServer_result implements org.apache.thrift.TBase<pingTabletServer_result, pingTabletServer_result._Fields>, java.io.Serializable, Cloneable, Comparable<pingTabletServer_result>   {
@@ -63963,11 +64677,8 @@
     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 pingTabletServer_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new pingTabletServer_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pingTabletServer_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pingTabletServer_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -63977,10 +64688,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -64005,21 +64716,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -64028,20 +64739,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pingTabletServer_result.class, metaDataMap);
     }
 
@@ -64127,7 +64838,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -64148,7 +64859,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -64157,13 +64868,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -64172,11 +64883,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof pingTabletServer_result)
@@ -64187,6 +64898,8 @@
     public boolean equals(pingTabletServer_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -64211,19 +64924,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -64234,7 +64945,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -64244,7 +64955,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -64262,16 +64973,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("pingTabletServer_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pingTabletServer_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -64306,7 +65017,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -64314,13 +65025,13 @@
       }
     }
 
-    private static class pingTabletServer_resultStandardSchemeFactory implements SchemeFactory {
+    private static class pingTabletServer_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public pingTabletServer_resultStandardScheme getScheme() {
         return new pingTabletServer_resultStandardScheme();
       }
     }
 
-    private static class pingTabletServer_resultStandardScheme extends StandardScheme<pingTabletServer_result> {
+    private static class pingTabletServer_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pingTabletServer_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, pingTabletServer_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -64381,18 +65092,18 @@
 
     }
 
-    private static class pingTabletServer_resultTupleSchemeFactory implements SchemeFactory {
+    private static class pingTabletServer_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public pingTabletServer_resultTupleScheme getScheme() {
         return new pingTabletServer_resultTupleScheme();
       }
     }
 
-    private static class pingTabletServer_resultTupleScheme extends TupleScheme<pingTabletServer_result> {
+    private static class pingTabletServer_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pingTabletServer_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, pingTabletServer_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -64410,8 +65121,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, pingTabletServer_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -64425,6 +65136,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getActiveScans_args implements org.apache.thrift.TBase<getActiveScans_args, getActiveScans_args._Fields>, java.io.Serializable, Cloneable, Comparable<getActiveScans_args>   {
@@ -64433,24 +65147,21 @@
     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 TSERVER_FIELD_DESC = new org.apache.thrift.protocol.TField("tserver", 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 getActiveScans_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getActiveScans_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getActiveScans_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getActiveScans_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tserver; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tserver; // 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"),
       TSERVER((short)2, "tserver");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -64475,21 +65186,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -64498,20 +65209,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TSERVER, new org.apache.thrift.meta_data.FieldMetaData("tserver", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getActiveScans_args.class, metaDataMap);
     }
 
@@ -64519,8 +65230,8 @@
     }
 
     public getActiveScans_args(
-      ByteBuffer login,
-      String tserver)
+      java.nio.ByteBuffer login,
+      java.lang.String tserver)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -64554,16 +65265,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getActiveScans_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getActiveScans_args setLogin(ByteBuffer login) {
+    public getActiveScans_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -64583,11 +65294,11 @@
       }
     }
 
-    public String getTserver() {
+    public java.lang.String getTserver() {
       return this.tserver;
     }
 
-    public getActiveScans_args setTserver(String tserver) {
+    public getActiveScans_args setTserver(java.lang.String tserver) {
       this.tserver = tserver;
       return this;
     }
@@ -64607,13 +65318,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -64621,14 +65336,14 @@
         if (value == null) {
           unsetTserver();
         } else {
-          setTserver((String)value);
+          setTserver((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -64637,13 +65352,13 @@
         return getTserver();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -64652,11 +65367,11 @@
       case TSERVER:
         return isSetTserver();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getActiveScans_args)
@@ -64667,6 +65382,8 @@
     public boolean equals(getActiveScans_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -64691,19 +65408,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tserver = true && (isSetTserver());
-      list.add(present_tserver);
-      if (present_tserver)
-        list.add(tserver);
+      hashCode = hashCode * 8191 + ((isSetTserver()) ? 131071 : 524287);
+      if (isSetTserver())
+        hashCode = hashCode * 8191 + tserver.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -64714,7 +65429,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -64724,7 +65439,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTserver()).compareTo(other.isSetTserver());
+      lastComparison = java.lang.Boolean.valueOf(isSetTserver()).compareTo(other.isSetTserver());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -64742,16 +65457,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getActiveScans_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getActiveScans_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -64786,7 +65501,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -64794,13 +65509,13 @@
       }
     }
 
-    private static class getActiveScans_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getActiveScans_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getActiveScans_argsStandardScheme getScheme() {
         return new getActiveScans_argsStandardScheme();
       }
     }
 
-    private static class getActiveScans_argsStandardScheme extends StandardScheme<getActiveScans_args> {
+    private static class getActiveScans_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getActiveScans_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getActiveScans_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -64859,18 +65574,18 @@
 
     }
 
-    private static class getActiveScans_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getActiveScans_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getActiveScans_argsTupleScheme getScheme() {
         return new getActiveScans_argsTupleScheme();
       }
     }
 
-    private static class getActiveScans_argsTupleScheme extends TupleScheme<getActiveScans_args> {
+    private static class getActiveScans_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getActiveScans_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getActiveScans_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -64888,8 +65603,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getActiveScans_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -64901,6 +65616,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getActiveScans_result implements org.apache.thrift.TBase<getActiveScans_result, getActiveScans_result._Fields>, java.io.Serializable, Cloneable, Comparable<getActiveScans_result>   {
@@ -64910,13 +65628,10 @@
     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 getActiveScans_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getActiveScans_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getActiveScans_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getActiveScans_resultTupleSchemeFactory();
 
-    public List<ActiveScan> success; // required
+    public java.util.List<ActiveScan> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
 
@@ -64926,10 +65641,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -64956,21 +65671,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -64979,23 +65694,23 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ActiveScan.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getActiveScans_result.class, metaDataMap);
     }
 
@@ -65003,7 +65718,7 @@
     }
 
     public getActiveScans_result(
-      List<ActiveScan> success,
+      java.util.List<ActiveScan> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2)
     {
@@ -65018,7 +65733,7 @@
      */
     public getActiveScans_result(getActiveScans_result other) {
       if (other.isSetSuccess()) {
-        List<ActiveScan> __this__success = new ArrayList<ActiveScan>(other.success.size());
+        java.util.List<ActiveScan> __this__success = new java.util.ArrayList<ActiveScan>(other.success.size());
         for (ActiveScan other_element : other.success) {
           __this__success.add(new ActiveScan(other_element));
         }
@@ -65053,16 +65768,16 @@
 
     public void addToSuccess(ActiveScan elem) {
       if (this.success == null) {
-        this.success = new ArrayList<ActiveScan>();
+        this.success = new java.util.ArrayList<ActiveScan>();
       }
       this.success.add(elem);
     }
 
-    public List<ActiveScan> getSuccess() {
+    public java.util.List<ActiveScan> getSuccess() {
       return this.success;
     }
 
-    public getActiveScans_result setSuccess(List<ActiveScan> success) {
+    public getActiveScans_result setSuccess(java.util.List<ActiveScan> success) {
       this.success = success;
       return this;
     }
@@ -65130,13 +65845,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((List<ActiveScan>)value);
+          setSuccess((java.util.List<ActiveScan>)value);
         }
         break;
 
@@ -65159,7 +65874,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -65171,13 +65886,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -65188,11 +65903,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getActiveScans_result)
@@ -65203,6 +65918,8 @@
     public boolean equals(getActiveScans_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -65236,24 +65953,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -65264,7 +65978,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -65274,7 +65988,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -65284,7 +65998,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -65302,16 +66016,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getActiveScans_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getActiveScans_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -65354,7 +66068,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -65362,13 +66076,13 @@
       }
     }
 
-    private static class getActiveScans_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getActiveScans_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getActiveScans_resultStandardScheme getScheme() {
         return new getActiveScans_resultStandardScheme();
       }
     }
 
-    private static class getActiveScans_resultStandardScheme extends StandardScheme<getActiveScans_result> {
+    private static class getActiveScans_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getActiveScans_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getActiveScans_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -65384,7 +66098,7 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                 {
                   org.apache.thrift.protocol.TList _list364 = iprot.readListBegin();
-                  struct.success = new ArrayList<ActiveScan>(_list364.size);
+                  struct.success = new java.util.ArrayList<ActiveScan>(_list364.size);
                   ActiveScan _elem365;
                   for (int _i366 = 0; _i366 < _list364.size; ++_i366)
                   {
@@ -65460,18 +66174,18 @@
 
     }
 
-    private static class getActiveScans_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getActiveScans_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getActiveScans_resultTupleScheme getScheme() {
         return new getActiveScans_resultTupleScheme();
       }
     }
 
-    private static class getActiveScans_resultTupleScheme extends TupleScheme<getActiveScans_result> {
+    private static class getActiveScans_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getActiveScans_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getActiveScans_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -65501,12 +66215,12 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getActiveScans_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           {
             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);
+            struct.success = new java.util.ArrayList<ActiveScan>(_list369.size);
             ActiveScan _elem370;
             for (int _i371 = 0; _i371 < _list369.size; ++_i371)
             {
@@ -65530,6 +66244,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getActiveCompactions_args implements org.apache.thrift.TBase<getActiveCompactions_args, getActiveCompactions_args._Fields>, java.io.Serializable, Cloneable, Comparable<getActiveCompactions_args>   {
@@ -65538,24 +66255,21 @@
     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 TSERVER_FIELD_DESC = new org.apache.thrift.protocol.TField("tserver", 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 getActiveCompactions_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getActiveCompactions_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getActiveCompactions_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getActiveCompactions_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tserver; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tserver; // 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"),
       TSERVER((short)2, "tserver");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -65580,21 +66294,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -65603,20 +66317,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TSERVER, new org.apache.thrift.meta_data.FieldMetaData("tserver", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getActiveCompactions_args.class, metaDataMap);
     }
 
@@ -65624,8 +66338,8 @@
     }
 
     public getActiveCompactions_args(
-      ByteBuffer login,
-      String tserver)
+      java.nio.ByteBuffer login,
+      java.lang.String tserver)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -65659,16 +66373,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getActiveCompactions_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getActiveCompactions_args setLogin(ByteBuffer login) {
+    public getActiveCompactions_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -65688,11 +66402,11 @@
       }
     }
 
-    public String getTserver() {
+    public java.lang.String getTserver() {
       return this.tserver;
     }
 
-    public getActiveCompactions_args setTserver(String tserver) {
+    public getActiveCompactions_args setTserver(java.lang.String tserver) {
       this.tserver = tserver;
       return this;
     }
@@ -65712,13 +66426,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -65726,14 +66444,14 @@
         if (value == null) {
           unsetTserver();
         } else {
-          setTserver((String)value);
+          setTserver((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -65742,13 +66460,13 @@
         return getTserver();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -65757,11 +66475,11 @@
       case TSERVER:
         return isSetTserver();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getActiveCompactions_args)
@@ -65772,6 +66490,8 @@
     public boolean equals(getActiveCompactions_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -65796,19 +66516,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tserver = true && (isSetTserver());
-      list.add(present_tserver);
-      if (present_tserver)
-        list.add(tserver);
+      hashCode = hashCode * 8191 + ((isSetTserver()) ? 131071 : 524287);
+      if (isSetTserver())
+        hashCode = hashCode * 8191 + tserver.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -65819,7 +66537,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -65829,7 +66547,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTserver()).compareTo(other.isSetTserver());
+      lastComparison = java.lang.Boolean.valueOf(isSetTserver()).compareTo(other.isSetTserver());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -65847,16 +66565,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getActiveCompactions_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getActiveCompactions_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -65891,7 +66609,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -65899,13 +66617,13 @@
       }
     }
 
-    private static class getActiveCompactions_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getActiveCompactions_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getActiveCompactions_argsStandardScheme getScheme() {
         return new getActiveCompactions_argsStandardScheme();
       }
     }
 
-    private static class getActiveCompactions_argsStandardScheme extends StandardScheme<getActiveCompactions_args> {
+    private static class getActiveCompactions_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getActiveCompactions_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getActiveCompactions_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -65964,18 +66682,18 @@
 
     }
 
-    private static class getActiveCompactions_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getActiveCompactions_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getActiveCompactions_argsTupleScheme getScheme() {
         return new getActiveCompactions_argsTupleScheme();
       }
     }
 
-    private static class getActiveCompactions_argsTupleScheme extends TupleScheme<getActiveCompactions_args> {
+    private static class getActiveCompactions_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getActiveCompactions_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getActiveCompactions_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -65993,8 +66711,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getActiveCompactions_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -66006,6 +66724,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getActiveCompactions_result implements org.apache.thrift.TBase<getActiveCompactions_result, getActiveCompactions_result._Fields>, java.io.Serializable, Cloneable, Comparable<getActiveCompactions_result>   {
@@ -66015,13 +66736,10 @@
     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 getActiveCompactions_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getActiveCompactions_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getActiveCompactions_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getActiveCompactions_resultTupleSchemeFactory();
 
-    public List<ActiveCompaction> success; // required
+    public java.util.List<ActiveCompaction> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
 
@@ -66031,10 +66749,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -66061,21 +66779,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -66084,23 +66802,23 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ActiveCompaction.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getActiveCompactions_result.class, metaDataMap);
     }
 
@@ -66108,7 +66826,7 @@
     }
 
     public getActiveCompactions_result(
-      List<ActiveCompaction> success,
+      java.util.List<ActiveCompaction> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2)
     {
@@ -66123,7 +66841,7 @@
      */
     public getActiveCompactions_result(getActiveCompactions_result other) {
       if (other.isSetSuccess()) {
-        List<ActiveCompaction> __this__success = new ArrayList<ActiveCompaction>(other.success.size());
+        java.util.List<ActiveCompaction> __this__success = new java.util.ArrayList<ActiveCompaction>(other.success.size());
         for (ActiveCompaction other_element : other.success) {
           __this__success.add(new ActiveCompaction(other_element));
         }
@@ -66158,16 +66876,16 @@
 
     public void addToSuccess(ActiveCompaction elem) {
       if (this.success == null) {
-        this.success = new ArrayList<ActiveCompaction>();
+        this.success = new java.util.ArrayList<ActiveCompaction>();
       }
       this.success.add(elem);
     }
 
-    public List<ActiveCompaction> getSuccess() {
+    public java.util.List<ActiveCompaction> getSuccess() {
       return this.success;
     }
 
-    public getActiveCompactions_result setSuccess(List<ActiveCompaction> success) {
+    public getActiveCompactions_result setSuccess(java.util.List<ActiveCompaction> success) {
       this.success = success;
       return this;
     }
@@ -66235,13 +66953,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((List<ActiveCompaction>)value);
+          setSuccess((java.util.List<ActiveCompaction>)value);
         }
         break;
 
@@ -66264,7 +66982,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -66276,13 +66994,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -66293,11 +67011,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getActiveCompactions_result)
@@ -66308,6 +67026,8 @@
     public boolean equals(getActiveCompactions_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -66341,24 +67061,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -66369,7 +67086,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -66379,7 +67096,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -66389,7 +67106,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -66407,16 +67124,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getActiveCompactions_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getActiveCompactions_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -66459,7 +67176,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -66467,13 +67184,13 @@
       }
     }
 
-    private static class getActiveCompactions_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getActiveCompactions_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getActiveCompactions_resultStandardScheme getScheme() {
         return new getActiveCompactions_resultStandardScheme();
       }
     }
 
-    private static class getActiveCompactions_resultStandardScheme extends StandardScheme<getActiveCompactions_result> {
+    private static class getActiveCompactions_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getActiveCompactions_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getActiveCompactions_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -66489,7 +67206,7 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                 {
                   org.apache.thrift.protocol.TList _list372 = iprot.readListBegin();
-                  struct.success = new ArrayList<ActiveCompaction>(_list372.size);
+                  struct.success = new java.util.ArrayList<ActiveCompaction>(_list372.size);
                   ActiveCompaction _elem373;
                   for (int _i374 = 0; _i374 < _list372.size; ++_i374)
                   {
@@ -66565,18 +67282,18 @@
 
     }
 
-    private static class getActiveCompactions_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getActiveCompactions_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getActiveCompactions_resultTupleScheme getScheme() {
         return new getActiveCompactions_resultTupleScheme();
       }
     }
 
-    private static class getActiveCompactions_resultTupleScheme extends TupleScheme<getActiveCompactions_result> {
+    private static class getActiveCompactions_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getActiveCompactions_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getActiveCompactions_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -66606,12 +67323,12 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getActiveCompactions_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           {
             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);
+            struct.success = new java.util.ArrayList<ActiveCompaction>(_list377.size);
             ActiveCompaction _elem378;
             for (int _i379 = 0; _i379 < _list377.size; ++_i379)
             {
@@ -66635,6 +67352,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getSiteConfiguration_args implements org.apache.thrift.TBase<getSiteConfiguration_args, getSiteConfiguration_args._Fields>, java.io.Serializable, Cloneable, Comparable<getSiteConfiguration_args>   {
@@ -66642,22 +67362,19 @@
 
     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 getSiteConfiguration_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getSiteConfiguration_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getSiteConfiguration_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getSiteConfiguration_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
+    public java.nio.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -66680,21 +67397,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -66703,18 +67420,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSiteConfiguration_args.class, metaDataMap);
     }
 
@@ -66722,7 +67439,7 @@
     }
 
     public getSiteConfiguration_args(
-      ByteBuffer login)
+      java.nio.ByteBuffer login)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -66751,16 +67468,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getSiteConfiguration_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getSiteConfiguration_args setLogin(ByteBuffer login) {
+    public getSiteConfiguration_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -66780,43 +67497,47 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case LOGIN:
         return isSetLogin();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getSiteConfiguration_args)
@@ -66827,6 +67548,8 @@
     public boolean equals(getSiteConfiguration_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -66842,14 +67565,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -66860,7 +67582,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -66878,16 +67600,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getSiteConfiguration_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getSiteConfiguration_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -66914,7 +67636,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -66922,13 +67644,13 @@
       }
     }
 
-    private static class getSiteConfiguration_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getSiteConfiguration_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getSiteConfiguration_argsStandardScheme getScheme() {
         return new getSiteConfiguration_argsStandardScheme();
       }
     }
 
-    private static class getSiteConfiguration_argsStandardScheme extends StandardScheme<getSiteConfiguration_args> {
+    private static class getSiteConfiguration_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getSiteConfiguration_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getSiteConfiguration_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -66974,18 +67696,18 @@
 
     }
 
-    private static class getSiteConfiguration_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getSiteConfiguration_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getSiteConfiguration_argsTupleScheme getScheme() {
         return new getSiteConfiguration_argsTupleScheme();
       }
     }
 
-    private static class getSiteConfiguration_argsTupleScheme extends TupleScheme<getSiteConfiguration_args> {
+    private static class getSiteConfiguration_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getSiteConfiguration_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getSiteConfiguration_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -66997,8 +67719,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getSiteConfiguration_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -67006,6 +67728,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getSiteConfiguration_result implements org.apache.thrift.TBase<getSiteConfiguration_result, getSiteConfiguration_result._Fields>, java.io.Serializable, Cloneable, Comparable<getSiteConfiguration_result>   {
@@ -67015,13 +67740,10 @@
     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 getSiteConfiguration_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getSiteConfiguration_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getSiteConfiguration_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getSiteConfiguration_resultTupleSchemeFactory();
 
-    public Map<String,String> success; // required
+    public java.util.Map<java.lang.String,java.lang.String> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
 
@@ -67031,10 +67753,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -67061,21 +67783,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -67084,24 +67806,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSiteConfiguration_result.class, metaDataMap);
     }
 
@@ -67109,7 +67831,7 @@
     }
 
     public getSiteConfiguration_result(
-      Map<String,String> success,
+      java.util.Map<java.lang.String,java.lang.String> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2)
     {
@@ -67124,7 +67846,7 @@
      */
     public getSiteConfiguration_result(getSiteConfiguration_result other) {
       if (other.isSetSuccess()) {
-        Map<String,String> __this__success = new HashMap<String,String>(other.success);
+        java.util.Map<java.lang.String,java.lang.String> __this__success = new java.util.HashMap<java.lang.String,java.lang.String>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -67150,18 +67872,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, String val) {
+    public void putToSuccess(java.lang.String key, java.lang.String val) {
       if (this.success == null) {
-        this.success = new HashMap<String,String>();
+        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,String> getSuccess() {
+    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
       return this.success;
     }
 
-    public getSiteConfiguration_result setSuccess(Map<String,String> success) {
+    public getSiteConfiguration_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
       this.success = success;
       return this;
     }
@@ -67229,13 +67951,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,String>)value);
+          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
         }
         break;
 
@@ -67258,7 +67980,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -67270,13 +67992,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -67287,11 +68009,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getSiteConfiguration_result)
@@ -67302,6 +68024,8 @@
     public boolean equals(getSiteConfiguration_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -67335,24 +68059,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -67363,7 +68084,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -67373,7 +68094,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -67383,7 +68104,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -67401,16 +68122,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getSiteConfiguration_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getSiteConfiguration_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -67453,7 +68174,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -67461,13 +68182,13 @@
       }
     }
 
-    private static class getSiteConfiguration_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getSiteConfiguration_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getSiteConfiguration_resultStandardScheme getScheme() {
         return new getSiteConfiguration_resultStandardScheme();
       }
     }
 
-    private static class getSiteConfiguration_resultStandardScheme extends StandardScheme<getSiteConfiguration_result> {
+    private static class getSiteConfiguration_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getSiteConfiguration_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getSiteConfiguration_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -67483,9 +68204,9 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map380 = iprot.readMapBegin();
-                  struct.success = new HashMap<String,String>(2*_map380.size);
-                  String _key381;
-                  String _val382;
+                  struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map380.size);
+                  java.lang.String _key381;
+                  java.lang.String _val382;
                   for (int _i383 = 0; _i383 < _map380.size; ++_i383)
                   {
                     _key381 = iprot.readString();
@@ -67536,7 +68257,7 @@
           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> _iter384 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter384 : struct.success.entrySet())
             {
               oprot.writeString(_iter384.getKey());
               oprot.writeString(_iter384.getValue());
@@ -67561,18 +68282,18 @@
 
     }
 
-    private static class getSiteConfiguration_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getSiteConfiguration_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getSiteConfiguration_resultTupleScheme getScheme() {
         return new getSiteConfiguration_resultTupleScheme();
       }
     }
 
-    private static class getSiteConfiguration_resultTupleScheme extends TupleScheme<getSiteConfiguration_result> {
+    private static class getSiteConfiguration_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getSiteConfiguration_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getSiteConfiguration_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -67586,7 +68307,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, String> _iter385 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter385 : struct.success.entrySet())
             {
               oprot.writeString(_iter385.getKey());
               oprot.writeString(_iter385.getValue());
@@ -67603,14 +68324,14 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getSiteConfiguration_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           {
             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);
-            String _key387;
-            String _val388;
+            struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map386.size);
+            java.lang.String _key387;
+            java.lang.String _val388;
             for (int _i389 = 0; _i389 < _map386.size; ++_i389)
             {
               _key387 = iprot.readString();
@@ -67633,6 +68354,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getSystemConfiguration_args implements org.apache.thrift.TBase<getSystemConfiguration_args, getSystemConfiguration_args._Fields>, java.io.Serializable, Cloneable, Comparable<getSystemConfiguration_args>   {
@@ -67640,22 +68364,19 @@
 
     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 getSystemConfiguration_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getSystemConfiguration_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getSystemConfiguration_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getSystemConfiguration_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
+    public java.nio.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -67678,21 +68399,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -67701,18 +68422,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSystemConfiguration_args.class, metaDataMap);
     }
 
@@ -67720,7 +68441,7 @@
     }
 
     public getSystemConfiguration_args(
-      ByteBuffer login)
+      java.nio.ByteBuffer login)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -67749,16 +68470,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getSystemConfiguration_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getSystemConfiguration_args setLogin(ByteBuffer login) {
+    public getSystemConfiguration_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -67778,43 +68499,47 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case LOGIN:
         return isSetLogin();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getSystemConfiguration_args)
@@ -67825,6 +68550,8 @@
     public boolean equals(getSystemConfiguration_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -67840,14 +68567,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -67858,7 +68584,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -67876,16 +68602,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getSystemConfiguration_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getSystemConfiguration_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -67912,7 +68638,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -67920,13 +68646,13 @@
       }
     }
 
-    private static class getSystemConfiguration_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getSystemConfiguration_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getSystemConfiguration_argsStandardScheme getScheme() {
         return new getSystemConfiguration_argsStandardScheme();
       }
     }
 
-    private static class getSystemConfiguration_argsStandardScheme extends StandardScheme<getSystemConfiguration_args> {
+    private static class getSystemConfiguration_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getSystemConfiguration_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getSystemConfiguration_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -67972,18 +68698,18 @@
 
     }
 
-    private static class getSystemConfiguration_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getSystemConfiguration_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getSystemConfiguration_argsTupleScheme getScheme() {
         return new getSystemConfiguration_argsTupleScheme();
       }
     }
 
-    private static class getSystemConfiguration_argsTupleScheme extends TupleScheme<getSystemConfiguration_args> {
+    private static class getSystemConfiguration_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getSystemConfiguration_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getSystemConfiguration_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -67995,8 +68721,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getSystemConfiguration_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -68004,6 +68730,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getSystemConfiguration_result implements org.apache.thrift.TBase<getSystemConfiguration_result, getSystemConfiguration_result._Fields>, java.io.Serializable, Cloneable, Comparable<getSystemConfiguration_result>   {
@@ -68013,13 +68742,10 @@
     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 getSystemConfiguration_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getSystemConfiguration_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getSystemConfiguration_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getSystemConfiguration_resultTupleSchemeFactory();
 
-    public Map<String,String> success; // required
+    public java.util.Map<java.lang.String,java.lang.String> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
 
@@ -68029,10 +68755,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -68059,21 +68785,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -68082,24 +68808,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getSystemConfiguration_result.class, metaDataMap);
     }
 
@@ -68107,7 +68833,7 @@
     }
 
     public getSystemConfiguration_result(
-      Map<String,String> success,
+      java.util.Map<java.lang.String,java.lang.String> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2)
     {
@@ -68122,7 +68848,7 @@
      */
     public getSystemConfiguration_result(getSystemConfiguration_result other) {
       if (other.isSetSuccess()) {
-        Map<String,String> __this__success = new HashMap<String,String>(other.success);
+        java.util.Map<java.lang.String,java.lang.String> __this__success = new java.util.HashMap<java.lang.String,java.lang.String>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -68148,18 +68874,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, String val) {
+    public void putToSuccess(java.lang.String key, java.lang.String val) {
       if (this.success == null) {
-        this.success = new HashMap<String,String>();
+        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,String> getSuccess() {
+    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
       return this.success;
     }
 
-    public getSystemConfiguration_result setSuccess(Map<String,String> success) {
+    public getSystemConfiguration_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
       this.success = success;
       return this;
     }
@@ -68227,13 +68953,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,String>)value);
+          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
         }
         break;
 
@@ -68256,7 +68982,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -68268,13 +68994,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -68285,11 +69011,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getSystemConfiguration_result)
@@ -68300,6 +69026,8 @@
     public boolean equals(getSystemConfiguration_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -68333,24 +69061,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -68361,7 +69086,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -68371,7 +69096,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -68381,7 +69106,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -68399,16 +69124,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getSystemConfiguration_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getSystemConfiguration_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -68451,7 +69176,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -68459,13 +69184,13 @@
       }
     }
 
-    private static class getSystemConfiguration_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getSystemConfiguration_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getSystemConfiguration_resultStandardScheme getScheme() {
         return new getSystemConfiguration_resultStandardScheme();
       }
     }
 
-    private static class getSystemConfiguration_resultStandardScheme extends StandardScheme<getSystemConfiguration_result> {
+    private static class getSystemConfiguration_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getSystemConfiguration_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getSystemConfiguration_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -68481,9 +69206,9 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map390 = iprot.readMapBegin();
-                  struct.success = new HashMap<String,String>(2*_map390.size);
-                  String _key391;
-                  String _val392;
+                  struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map390.size);
+                  java.lang.String _key391;
+                  java.lang.String _val392;
                   for (int _i393 = 0; _i393 < _map390.size; ++_i393)
                   {
                     _key391 = iprot.readString();
@@ -68534,7 +69259,7 @@
           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> _iter394 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter394 : struct.success.entrySet())
             {
               oprot.writeString(_iter394.getKey());
               oprot.writeString(_iter394.getValue());
@@ -68559,18 +69284,18 @@
 
     }
 
-    private static class getSystemConfiguration_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getSystemConfiguration_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getSystemConfiguration_resultTupleScheme getScheme() {
         return new getSystemConfiguration_resultTupleScheme();
       }
     }
 
-    private static class getSystemConfiguration_resultTupleScheme extends TupleScheme<getSystemConfiguration_result> {
+    private static class getSystemConfiguration_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getSystemConfiguration_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getSystemConfiguration_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -68584,7 +69309,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, String> _iter395 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter395 : struct.success.entrySet())
             {
               oprot.writeString(_iter395.getKey());
               oprot.writeString(_iter395.getValue());
@@ -68601,14 +69326,14 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getSystemConfiguration_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           {
             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);
-            String _key397;
-            String _val398;
+            struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map396.size);
+            java.lang.String _key397;
+            java.lang.String _val398;
             for (int _i399 = 0; _i399 < _map396.size; ++_i399)
             {
               _key397 = iprot.readString();
@@ -68631,6 +69356,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getTabletServers_args implements org.apache.thrift.TBase<getTabletServers_args, getTabletServers_args._Fields>, java.io.Serializable, Cloneable, Comparable<getTabletServers_args>   {
@@ -68638,22 +69366,19 @@
 
     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 getTabletServers_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getTabletServers_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getTabletServers_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getTabletServers_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
+    public java.nio.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -68676,21 +69401,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -68699,18 +69424,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getTabletServers_args.class, metaDataMap);
     }
 
@@ -68718,7 +69443,7 @@
     }
 
     public getTabletServers_args(
-      ByteBuffer login)
+      java.nio.ByteBuffer login)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -68747,16 +69472,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getTabletServers_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getTabletServers_args setLogin(ByteBuffer login) {
+    public getTabletServers_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -68776,43 +69501,47 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case LOGIN:
         return isSetLogin();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getTabletServers_args)
@@ -68823,6 +69552,8 @@
     public boolean equals(getTabletServers_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -68838,14 +69569,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -68856,7 +69586,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -68874,16 +69604,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getTabletServers_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getTabletServers_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -68910,7 +69640,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -68918,13 +69648,13 @@
       }
     }
 
-    private static class getTabletServers_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getTabletServers_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getTabletServers_argsStandardScheme getScheme() {
         return new getTabletServers_argsStandardScheme();
       }
     }
 
-    private static class getTabletServers_argsStandardScheme extends StandardScheme<getTabletServers_args> {
+    private static class getTabletServers_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getTabletServers_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getTabletServers_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -68970,18 +69700,18 @@
 
     }
 
-    private static class getTabletServers_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getTabletServers_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getTabletServers_argsTupleScheme getScheme() {
         return new getTabletServers_argsTupleScheme();
       }
     }
 
-    private static class getTabletServers_argsTupleScheme extends TupleScheme<getTabletServers_args> {
+    private static class getTabletServers_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getTabletServers_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getTabletServers_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -68993,8 +69723,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getTabletServers_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -69002,6 +69732,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getTabletServers_result implements org.apache.thrift.TBase<getTabletServers_result, getTabletServers_result._Fields>, java.io.Serializable, Cloneable, Comparable<getTabletServers_result>   {
@@ -69009,22 +69742,19 @@
 
     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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new getTabletServers_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getTabletServers_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getTabletServers_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getTabletServers_resultTupleSchemeFactory();
 
-    public List<String> success; // required
+    public java.util.List<java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -69047,21 +69777,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -69070,19 +69800,19 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getTabletServers_result.class, metaDataMap);
     }
 
@@ -69090,7 +69820,7 @@
     }
 
     public getTabletServers_result(
-      List<String> success)
+      java.util.List<java.lang.String> success)
     {
       this();
       this.success = success;
@@ -69101,7 +69831,7 @@
      */
     public getTabletServers_result(getTabletServers_result other) {
       if (other.isSetSuccess()) {
-        List<String> __this__success = new ArrayList<String>(other.success);
+        java.util.List<java.lang.String> __this__success = new java.util.ArrayList<java.lang.String>(other.success);
         this.success = __this__success;
       }
     }
@@ -69119,22 +69849,22 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public java.util.Iterator<String> getSuccessIterator() {
+    public java.util.Iterator<java.lang.String> getSuccessIterator() {
       return (this.success == null) ? null : this.success.iterator();
     }
 
-    public void addToSuccess(String elem) {
+    public void addToSuccess(java.lang.String elem) {
       if (this.success == null) {
-        this.success = new ArrayList<String>();
+        this.success = new java.util.ArrayList<java.lang.String>();
       }
       this.success.add(elem);
     }
 
-    public List<String> getSuccess() {
+    public java.util.List<java.lang.String> getSuccess() {
       return this.success;
     }
 
-    public getTabletServers_result setSuccess(List<String> success) {
+    public getTabletServers_result setSuccess(java.util.List<java.lang.String> success) {
       this.success = success;
       return this;
     }
@@ -69154,43 +69884,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((List<String>)value);
+          setSuccess((java.util.List<java.lang.String>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SUCCESS:
         return isSetSuccess();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getTabletServers_result)
@@ -69201,6 +69931,8 @@
     public boolean equals(getTabletServers_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -69216,14 +69948,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -69234,7 +69965,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -69252,16 +69983,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getTabletServers_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getTabletServers_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -69288,7 +70019,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -69296,13 +70027,13 @@
       }
     }
 
-    private static class getTabletServers_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getTabletServers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getTabletServers_resultStandardScheme getScheme() {
         return new getTabletServers_resultStandardScheme();
       }
     }
 
-    private static class getTabletServers_resultStandardScheme extends StandardScheme<getTabletServers_result> {
+    private static class getTabletServers_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getTabletServers_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getTabletServers_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -69318,8 +70049,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                 {
                   org.apache.thrift.protocol.TList _list400 = iprot.readListBegin();
-                  struct.success = new ArrayList<String>(_list400.size);
-                  String _elem401;
+                  struct.success = new java.util.ArrayList<java.lang.String>(_list400.size);
+                  java.lang.String _elem401;
                   for (int _i402 = 0; _i402 < _list400.size; ++_i402)
                   {
                     _elem401 = iprot.readString();
@@ -69351,7 +70082,7 @@
           oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
           {
             oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
-            for (String _iter403 : struct.success)
+            for (java.lang.String _iter403 : struct.success)
             {
               oprot.writeString(_iter403);
             }
@@ -69365,18 +70096,18 @@
 
     }
 
-    private static class getTabletServers_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getTabletServers_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getTabletServers_resultTupleScheme getScheme() {
         return new getTabletServers_resultTupleScheme();
       }
     }
 
-    private static class getTabletServers_resultTupleScheme extends TupleScheme<getTabletServers_result> {
+    private static class getTabletServers_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getTabletServers_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getTabletServers_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -69384,7 +70115,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (String _iter404 : struct.success)
+            for (java.lang.String _iter404 : struct.success)
             {
               oprot.writeString(_iter404);
             }
@@ -69394,13 +70125,13 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getTabletServers_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           {
             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);
-            String _elem406;
+            struct.success = new java.util.ArrayList<java.lang.String>(_list405.size);
+            java.lang.String _elem406;
             for (int _i407 = 0; _i407 < _list405.size; ++_i407)
             {
               _elem406 = iprot.readString();
@@ -69412,6 +70143,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeProperty_args implements org.apache.thrift.TBase<removeProperty_args, removeProperty_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeProperty_args>   {
@@ -69420,24 +70154,21 @@
     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 PROPERTY_FIELD_DESC = new org.apache.thrift.protocol.TField("property", 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 removeProperty_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new removeProperty_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeProperty_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeProperty_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String property; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.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"),
       PROPERTY((short)2, "property");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -69462,21 +70193,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -69485,20 +70216,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeProperty_args.class, metaDataMap);
     }
 
@@ -69506,8 +70237,8 @@
     }
 
     public removeProperty_args(
-      ByteBuffer login,
-      String property)
+      java.nio.ByteBuffer login,
+      java.lang.String property)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -69541,16 +70272,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public removeProperty_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public removeProperty_args setLogin(ByteBuffer login) {
+    public removeProperty_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -69570,11 +70301,11 @@
       }
     }
 
-    public String getProperty() {
+    public java.lang.String getProperty() {
       return this.property;
     }
 
-    public removeProperty_args setProperty(String property) {
+    public removeProperty_args setProperty(java.lang.String property) {
       this.property = property;
       return this;
     }
@@ -69594,13 +70325,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -69608,14 +70343,14 @@
         if (value == null) {
           unsetProperty();
         } else {
-          setProperty((String)value);
+          setProperty((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -69624,13 +70359,13 @@
         return getProperty();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -69639,11 +70374,11 @@
       case PROPERTY:
         return isSetProperty();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeProperty_args)
@@ -69654,6 +70389,8 @@
     public boolean equals(removeProperty_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -69678,19 +70415,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_property = true && (isSetProperty());
-      list.add(present_property);
-      if (present_property)
-        list.add(property);
+      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
+      if (isSetProperty())
+        hashCode = hashCode * 8191 + property.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -69701,7 +70436,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -69711,7 +70446,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
+      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -69729,16 +70464,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeProperty_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeProperty_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -69773,7 +70508,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -69781,13 +70516,13 @@
       }
     }
 
-    private static class removeProperty_argsStandardSchemeFactory implements SchemeFactory {
+    private static class removeProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeProperty_argsStandardScheme getScheme() {
         return new removeProperty_argsStandardScheme();
       }
     }
 
-    private static class removeProperty_argsStandardScheme extends StandardScheme<removeProperty_args> {
+    private static class removeProperty_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeProperty_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, removeProperty_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -69846,18 +70581,18 @@
 
     }
 
-    private static class removeProperty_argsTupleSchemeFactory implements SchemeFactory {
+    private static class removeProperty_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeProperty_argsTupleScheme getScheme() {
         return new removeProperty_argsTupleScheme();
       }
     }
 
-    private static class removeProperty_argsTupleScheme extends TupleScheme<removeProperty_args> {
+    private static class removeProperty_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeProperty_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, removeProperty_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -69875,8 +70610,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, removeProperty_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -69888,6 +70623,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeProperty_result implements org.apache.thrift.TBase<removeProperty_result, removeProperty_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeProperty_result>   {
@@ -69896,11 +70634,8 @@
     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 removeProperty_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new removeProperty_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeProperty_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeProperty_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -69910,10 +70645,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -69938,21 +70673,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -69961,20 +70696,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeProperty_result.class, metaDataMap);
     }
 
@@ -70060,7 +70795,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -70081,7 +70816,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -70090,13 +70825,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -70105,11 +70840,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeProperty_result)
@@ -70120,6 +70855,8 @@
     public boolean equals(removeProperty_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -70144,19 +70881,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -70167,7 +70902,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -70177,7 +70912,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -70195,16 +70930,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeProperty_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeProperty_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -70239,7 +70974,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -70247,13 +70982,13 @@
       }
     }
 
-    private static class removeProperty_resultStandardSchemeFactory implements SchemeFactory {
+    private static class removeProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeProperty_resultStandardScheme getScheme() {
         return new removeProperty_resultStandardScheme();
       }
     }
 
-    private static class removeProperty_resultStandardScheme extends StandardScheme<removeProperty_result> {
+    private static class removeProperty_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeProperty_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, removeProperty_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -70314,18 +71049,18 @@
 
     }
 
-    private static class removeProperty_resultTupleSchemeFactory implements SchemeFactory {
+    private static class removeProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeProperty_resultTupleScheme getScheme() {
         return new removeProperty_resultTupleScheme();
       }
     }
 
-    private static class removeProperty_resultTupleScheme extends TupleScheme<removeProperty_result> {
+    private static class removeProperty_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeProperty_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, removeProperty_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -70343,8 +71078,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, removeProperty_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -70358,6 +71093,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class setProperty_args implements org.apache.thrift.TBase<setProperty_args, setProperty_args._Fields>, java.io.Serializable, Cloneable, Comparable<setProperty_args>   {
@@ -70367,15 +71105,12 @@
     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)2);
     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)3);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new setProperty_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new setProperty_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new setProperty_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new setProperty_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String property; // required
-    public String value; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String property; // required
+    public java.lang.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 {
@@ -70383,10 +71118,10 @@
       PROPERTY((short)2, "property"),
       VALUE((short)3, "value");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -70413,21 +71148,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -70436,22 +71171,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setProperty_args.class, metaDataMap);
     }
 
@@ -70459,9 +71194,9 @@
     }
 
     public setProperty_args(
-      ByteBuffer login,
-      String property,
-      String value)
+      java.nio.ByteBuffer login,
+      java.lang.String property,
+      java.lang.String value)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -70500,16 +71235,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public setProperty_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public setProperty_args setLogin(ByteBuffer login) {
+    public setProperty_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -70529,11 +71264,11 @@
       }
     }
 
-    public String getProperty() {
+    public java.lang.String getProperty() {
       return this.property;
     }
 
-    public setProperty_args setProperty(String property) {
+    public setProperty_args setProperty(java.lang.String property) {
       this.property = property;
       return this;
     }
@@ -70553,11 +71288,11 @@
       }
     }
 
-    public String getValue() {
+    public java.lang.String getValue() {
       return this.value;
     }
 
-    public setProperty_args setValue(String value) {
+    public setProperty_args setValue(java.lang.String value) {
       this.value = value;
       return this;
     }
@@ -70577,13 +71312,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -70591,7 +71330,7 @@
         if (value == null) {
           unsetProperty();
         } else {
-          setProperty((String)value);
+          setProperty((java.lang.String)value);
         }
         break;
 
@@ -70599,14 +71338,14 @@
         if (value == null) {
           unsetValue();
         } else {
-          setValue((String)value);
+          setValue((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -70618,13 +71357,13 @@
         return getValue();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -70635,11 +71374,11 @@
       case VALUE:
         return isSetValue();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof setProperty_args)
@@ -70650,6 +71389,8 @@
     public boolean equals(setProperty_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -70683,24 +71424,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_property = true && (isSetProperty());
-      list.add(present_property);
-      if (present_property)
-        list.add(property);
+      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
+      if (isSetProperty())
+        hashCode = hashCode * 8191 + property.hashCode();
 
-      boolean present_value = true && (isSetValue());
-      list.add(present_value);
-      if (present_value)
-        list.add(value);
+      hashCode = hashCode * 8191 + ((isSetValue()) ? 131071 : 524287);
+      if (isSetValue())
+        hashCode = hashCode * 8191 + value.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -70711,7 +71449,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -70721,7 +71459,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
+      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -70731,7 +71469,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
+      lastComparison = java.lang.Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -70749,16 +71487,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("setProperty_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("setProperty_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -70801,7 +71539,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -70809,13 +71547,13 @@
       }
     }
 
-    private static class setProperty_argsStandardSchemeFactory implements SchemeFactory {
+    private static class setProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setProperty_argsStandardScheme getScheme() {
         return new setProperty_argsStandardScheme();
       }
     }
 
-    private static class setProperty_argsStandardScheme extends StandardScheme<setProperty_args> {
+    private static class setProperty_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<setProperty_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, setProperty_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -70887,18 +71625,18 @@
 
     }
 
-    private static class setProperty_argsTupleSchemeFactory implements SchemeFactory {
+    private static class setProperty_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setProperty_argsTupleScheme getScheme() {
         return new setProperty_argsTupleScheme();
       }
     }
 
-    private static class setProperty_argsTupleScheme extends TupleScheme<setProperty_args> {
+    private static class setProperty_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<setProperty_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, setProperty_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -70922,8 +71660,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, setProperty_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -70939,6 +71677,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class setProperty_result implements org.apache.thrift.TBase<setProperty_result, setProperty_result._Fields>, java.io.Serializable, Cloneable, Comparable<setProperty_result>   {
@@ -70947,11 +71688,8 @@
     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 setProperty_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new setProperty_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new setProperty_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new setProperty_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -70961,10 +71699,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -70989,21 +71727,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -71012,20 +71750,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setProperty_result.class, metaDataMap);
     }
 
@@ -71111,7 +71849,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -71132,7 +71870,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -71141,13 +71879,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -71156,11 +71894,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof setProperty_result)
@@ -71171,6 +71909,8 @@
     public boolean equals(setProperty_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -71195,19 +71935,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -71218,7 +71956,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -71228,7 +71966,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -71246,16 +71984,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("setProperty_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("setProperty_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -71290,7 +72028,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -71298,13 +72036,13 @@
       }
     }
 
-    private static class setProperty_resultStandardSchemeFactory implements SchemeFactory {
+    private static class setProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setProperty_resultStandardScheme getScheme() {
         return new setProperty_resultStandardScheme();
       }
     }
 
-    private static class setProperty_resultStandardScheme extends StandardScheme<setProperty_result> {
+    private static class setProperty_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<setProperty_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, setProperty_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -71365,18 +72103,18 @@
 
     }
 
-    private static class setProperty_resultTupleSchemeFactory implements SchemeFactory {
+    private static class setProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setProperty_resultTupleScheme getScheme() {
         return new setProperty_resultTupleScheme();
       }
     }
 
-    private static class setProperty_resultTupleScheme extends TupleScheme<setProperty_result> {
+    private static class setProperty_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<setProperty_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, setProperty_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -71394,8 +72132,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, setProperty_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -71409,6 +72147,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class testClassLoad_args implements org.apache.thrift.TBase<testClassLoad_args, testClassLoad_args._Fields>, java.io.Serializable, Cloneable, Comparable<testClassLoad_args>   {
@@ -71418,15 +72159,12 @@
     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)2);
     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)3);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new testClassLoad_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new testClassLoad_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new testClassLoad_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new testClassLoad_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String className; // required
-    public String asTypeName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String className; // required
+    public java.lang.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 {
@@ -71434,10 +72172,10 @@
       CLASS_NAME((short)2, "className"),
       AS_TYPE_NAME((short)3, "asTypeName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -71464,21 +72202,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -71487,22 +72225,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testClassLoad_args.class, metaDataMap);
     }
 
@@ -71510,9 +72248,9 @@
     }
 
     public testClassLoad_args(
-      ByteBuffer login,
-      String className,
-      String asTypeName)
+      java.nio.ByteBuffer login,
+      java.lang.String className,
+      java.lang.String asTypeName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -71551,16 +72289,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public testClassLoad_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public testClassLoad_args setLogin(ByteBuffer login) {
+    public testClassLoad_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -71580,11 +72318,11 @@
       }
     }
 
-    public String getClassName() {
+    public java.lang.String getClassName() {
       return this.className;
     }
 
-    public testClassLoad_args setClassName(String className) {
+    public testClassLoad_args setClassName(java.lang.String className) {
       this.className = className;
       return this;
     }
@@ -71604,11 +72342,11 @@
       }
     }
 
-    public String getAsTypeName() {
+    public java.lang.String getAsTypeName() {
       return this.asTypeName;
     }
 
-    public testClassLoad_args setAsTypeName(String asTypeName) {
+    public testClassLoad_args setAsTypeName(java.lang.String asTypeName) {
       this.asTypeName = asTypeName;
       return this;
     }
@@ -71628,13 +72366,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -71642,7 +72384,7 @@
         if (value == null) {
           unsetClassName();
         } else {
-          setClassName((String)value);
+          setClassName((java.lang.String)value);
         }
         break;
 
@@ -71650,14 +72392,14 @@
         if (value == null) {
           unsetAsTypeName();
         } else {
-          setAsTypeName((String)value);
+          setAsTypeName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -71669,13 +72411,13 @@
         return getAsTypeName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -71686,11 +72428,11 @@
       case AS_TYPE_NAME:
         return isSetAsTypeName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof testClassLoad_args)
@@ -71701,6 +72443,8 @@
     public boolean equals(testClassLoad_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -71734,24 +72478,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_className = true && (isSetClassName());
-      list.add(present_className);
-      if (present_className)
-        list.add(className);
+      hashCode = hashCode * 8191 + ((isSetClassName()) ? 131071 : 524287);
+      if (isSetClassName())
+        hashCode = hashCode * 8191 + className.hashCode();
 
-      boolean present_asTypeName = true && (isSetAsTypeName());
-      list.add(present_asTypeName);
-      if (present_asTypeName)
-        list.add(asTypeName);
+      hashCode = hashCode * 8191 + ((isSetAsTypeName()) ? 131071 : 524287);
+      if (isSetAsTypeName())
+        hashCode = hashCode * 8191 + asTypeName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -71762,7 +72503,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -71772,7 +72513,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
+      lastComparison = java.lang.Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -71782,7 +72523,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetAsTypeName()).compareTo(other.isSetAsTypeName());
+      lastComparison = java.lang.Boolean.valueOf(isSetAsTypeName()).compareTo(other.isSetAsTypeName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -71800,16 +72541,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("testClassLoad_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("testClassLoad_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -71852,7 +72593,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -71860,13 +72601,13 @@
       }
     }
 
-    private static class testClassLoad_argsStandardSchemeFactory implements SchemeFactory {
+    private static class testClassLoad_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testClassLoad_argsStandardScheme getScheme() {
         return new testClassLoad_argsStandardScheme();
       }
     }
 
-    private static class testClassLoad_argsStandardScheme extends StandardScheme<testClassLoad_args> {
+    private static class testClassLoad_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<testClassLoad_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, testClassLoad_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -71938,18 +72679,18 @@
 
     }
 
-    private static class testClassLoad_argsTupleSchemeFactory implements SchemeFactory {
+    private static class testClassLoad_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testClassLoad_argsTupleScheme getScheme() {
         return new testClassLoad_argsTupleScheme();
       }
     }
 
-    private static class testClassLoad_argsTupleScheme extends TupleScheme<testClassLoad_args> {
+    private static class testClassLoad_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<testClassLoad_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, testClassLoad_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -71973,8 +72714,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, testClassLoad_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -71990,6 +72731,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class testClassLoad_result implements org.apache.thrift.TBase<testClassLoad_result, testClassLoad_result._Fields>, java.io.Serializable, Cloneable, Comparable<testClassLoad_result>   {
@@ -71999,11 +72743,8 @@
     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 testClassLoad_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new testClassLoad_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new testClassLoad_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new testClassLoad_resultTupleSchemeFactory();
 
     public boolean success; // required
     public AccumuloException ouch1; // required
@@ -72015,10 +72756,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -72045,21 +72786,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -72068,7 +72809,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -72076,16 +72817,16 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testClassLoad_result.class, metaDataMap);
     }
 
@@ -72141,16 +72882,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public AccumuloException getOuch1() {
@@ -72201,13 +72942,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Boolean)value);
+          setSuccess((java.lang.Boolean)value);
         }
         break;
 
@@ -72230,7 +72971,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return isSuccess();
@@ -72242,13 +72983,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -72259,11 +73000,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof testClassLoad_result)
@@ -72274,6 +73015,8 @@
     public boolean equals(testClassLoad_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -72307,24 +73050,19 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -72335,7 +73073,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -72345,7 +73083,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -72355,7 +73093,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -72373,16 +73111,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("testClassLoad_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("testClassLoad_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -72421,7 +73159,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -72431,13 +73169,13 @@
       }
     }
 
-    private static class testClassLoad_resultStandardSchemeFactory implements SchemeFactory {
+    private static class testClassLoad_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testClassLoad_resultStandardScheme getScheme() {
         return new testClassLoad_resultStandardScheme();
       }
     }
 
-    private static class testClassLoad_resultStandardScheme extends StandardScheme<testClassLoad_result> {
+    private static class testClassLoad_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<testClassLoad_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, testClassLoad_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -72511,18 +73249,18 @@
 
     }
 
-    private static class testClassLoad_resultTupleSchemeFactory implements SchemeFactory {
+    private static class testClassLoad_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testClassLoad_resultTupleScheme getScheme() {
         return new testClassLoad_resultTupleScheme();
       }
     }
 
-    private static class testClassLoad_resultTupleScheme extends TupleScheme<testClassLoad_result> {
+    private static class testClassLoad_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<testClassLoad_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, testClassLoad_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -72546,8 +73284,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, testClassLoad_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.success = iprot.readBool();
           struct.setSuccessIsSet(true);
@@ -72565,6 +73303,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class authenticateUser_args implements org.apache.thrift.TBase<authenticateUser_args, authenticateUser_args._Fields>, java.io.Serializable, Cloneable, Comparable<authenticateUser_args>   {
@@ -72574,15 +73315,12 @@
     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 PROPERTIES_FIELD_DESC = new org.apache.thrift.protocol.TField("properties", org.apache.thrift.protocol.TType.MAP, (short)3);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new authenticateUser_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new authenticateUser_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new authenticateUser_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new authenticateUser_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
-    public Map<String,String> properties; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
+    public java.util.Map<java.lang.String,java.lang.String> properties; // 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 {
@@ -72590,10 +73328,10 @@
       USER((short)2, "user"),
       PROPERTIES((short)3, "properties");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -72620,21 +73358,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -72643,15 +73381,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -72660,7 +73398,7 @@
           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))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(authenticateUser_args.class, metaDataMap);
     }
 
@@ -72668,9 +73406,9 @@
     }
 
     public authenticateUser_args(
-      ByteBuffer login,
-      String user,
-      Map<String,String> properties)
+      java.nio.ByteBuffer login,
+      java.lang.String user,
+      java.util.Map<java.lang.String,java.lang.String> properties)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -72689,7 +73427,7 @@
         this.user = other.user;
       }
       if (other.isSetProperties()) {
-        Map<String,String> __this__properties = new HashMap<String,String>(other.properties);
+        java.util.Map<java.lang.String,java.lang.String> __this__properties = new java.util.HashMap<java.lang.String,java.lang.String>(other.properties);
         this.properties = __this__properties;
       }
     }
@@ -72710,16 +73448,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public authenticateUser_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public authenticateUser_args setLogin(ByteBuffer login) {
+    public authenticateUser_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -72739,11 +73477,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public authenticateUser_args setUser(String user) {
+    public authenticateUser_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -72767,18 +73505,18 @@
       return (this.properties == null) ? 0 : this.properties.size();
     }
 
-    public void putToProperties(String key, String val) {
+    public void putToProperties(java.lang.String key, java.lang.String val) {
       if (this.properties == null) {
-        this.properties = new HashMap<String,String>();
+        this.properties = new java.util.HashMap<java.lang.String,java.lang.String>();
       }
       this.properties.put(key, val);
     }
 
-    public Map<String,String> getProperties() {
+    public java.util.Map<java.lang.String,java.lang.String> getProperties() {
       return this.properties;
     }
 
-    public authenticateUser_args setProperties(Map<String,String> properties) {
+    public authenticateUser_args setProperties(java.util.Map<java.lang.String,java.lang.String> properties) {
       this.properties = properties;
       return this;
     }
@@ -72798,13 +73536,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -72812,7 +73554,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -72820,14 +73562,14 @@
         if (value == null) {
           unsetProperties();
         } else {
-          setProperties((Map<String,String>)value);
+          setProperties((java.util.Map<java.lang.String,java.lang.String>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -72839,13 +73581,13 @@
         return getProperties();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -72856,11 +73598,11 @@
       case PROPERTIES:
         return isSetProperties();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof authenticateUser_args)
@@ -72871,6 +73613,8 @@
     public boolean equals(authenticateUser_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -72904,24 +73648,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_properties = true && (isSetProperties());
-      list.add(present_properties);
-      if (present_properties)
-        list.add(properties);
+      hashCode = hashCode * 8191 + ((isSetProperties()) ? 131071 : 524287);
+      if (isSetProperties())
+        hashCode = hashCode * 8191 + properties.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -72932,7 +73673,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -72942,7 +73683,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -72952,7 +73693,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetProperties()).compareTo(other.isSetProperties());
+      lastComparison = java.lang.Boolean.valueOf(isSetProperties()).compareTo(other.isSetProperties());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -72970,16 +73711,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("authenticateUser_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("authenticateUser_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -73022,7 +73763,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -73030,13 +73771,13 @@
       }
     }
 
-    private static class authenticateUser_argsStandardSchemeFactory implements SchemeFactory {
+    private static class authenticateUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public authenticateUser_argsStandardScheme getScheme() {
         return new authenticateUser_argsStandardScheme();
       }
     }
 
-    private static class authenticateUser_argsStandardScheme extends StandardScheme<authenticateUser_args> {
+    private static class authenticateUser_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<authenticateUser_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, authenticateUser_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -73068,9 +73809,9 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map408 = iprot.readMapBegin();
-                  struct.properties = new HashMap<String,String>(2*_map408.size);
-                  String _key409;
-                  String _val410;
+                  struct.properties = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map408.size);
+                  java.lang.String _key409;
+                  java.lang.String _val410;
                   for (int _i411 = 0; _i411 < _map408.size; ++_i411)
                   {
                     _key409 = iprot.readString();
@@ -73113,7 +73854,7 @@
           oprot.writeFieldBegin(PROPERTIES_FIELD_DESC);
           {
             oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.properties.size()));
-            for (Map.Entry<String, String> _iter412 : struct.properties.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter412 : struct.properties.entrySet())
             {
               oprot.writeString(_iter412.getKey());
               oprot.writeString(_iter412.getValue());
@@ -73128,18 +73869,18 @@
 
     }
 
-    private static class authenticateUser_argsTupleSchemeFactory implements SchemeFactory {
+    private static class authenticateUser_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public authenticateUser_argsTupleScheme getScheme() {
         return new authenticateUser_argsTupleScheme();
       }
     }
 
-    private static class authenticateUser_argsTupleScheme extends TupleScheme<authenticateUser_args> {
+    private static class authenticateUser_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<authenticateUser_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, authenticateUser_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -73159,7 +73900,7 @@
         if (struct.isSetProperties()) {
           {
             oprot.writeI32(struct.properties.size());
-            for (Map.Entry<String, String> _iter413 : struct.properties.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter413 : struct.properties.entrySet())
             {
               oprot.writeString(_iter413.getKey());
               oprot.writeString(_iter413.getValue());
@@ -73170,8 +73911,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, authenticateUser_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -73183,9 +73924,9 @@
         if (incoming.get(2)) {
           {
             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);
-            String _key415;
-            String _val416;
+            struct.properties = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map414.size);
+            java.lang.String _key415;
+            java.lang.String _val416;
             for (int _i417 = 0; _i417 < _map414.size; ++_i417)
             {
               _key415 = iprot.readString();
@@ -73198,6 +73939,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class authenticateUser_result implements org.apache.thrift.TBase<authenticateUser_result, authenticateUser_result._Fields>, java.io.Serializable, Cloneable, Comparable<authenticateUser_result>   {
@@ -73207,11 +73951,8 @@
     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 authenticateUser_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new authenticateUser_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new authenticateUser_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new authenticateUser_resultTupleSchemeFactory();
 
     public boolean success; // required
     public AccumuloException ouch1; // required
@@ -73223,10 +73964,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -73253,21 +73994,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -73276,7 +74017,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -73284,16 +74025,16 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(authenticateUser_result.class, metaDataMap);
     }
 
@@ -73349,16 +74090,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public AccumuloException getOuch1() {
@@ -73409,13 +74150,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Boolean)value);
+          setSuccess((java.lang.Boolean)value);
         }
         break;
 
@@ -73438,7 +74179,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return isSuccess();
@@ -73450,13 +74191,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -73467,11 +74208,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof authenticateUser_result)
@@ -73482,6 +74223,8 @@
     public boolean equals(authenticateUser_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -73515,24 +74258,19 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -73543,7 +74281,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -73553,7 +74291,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -73563,7 +74301,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -73581,16 +74319,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("authenticateUser_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("authenticateUser_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -73629,7 +74367,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -73639,13 +74377,13 @@
       }
     }
 
-    private static class authenticateUser_resultStandardSchemeFactory implements SchemeFactory {
+    private static class authenticateUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public authenticateUser_resultStandardScheme getScheme() {
         return new authenticateUser_resultStandardScheme();
       }
     }
 
-    private static class authenticateUser_resultStandardScheme extends StandardScheme<authenticateUser_result> {
+    private static class authenticateUser_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<authenticateUser_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, authenticateUser_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -73719,18 +74457,18 @@
 
     }
 
-    private static class authenticateUser_resultTupleSchemeFactory implements SchemeFactory {
+    private static class authenticateUser_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public authenticateUser_resultTupleScheme getScheme() {
         return new authenticateUser_resultTupleScheme();
       }
     }
 
-    private static class authenticateUser_resultTupleScheme extends TupleScheme<authenticateUser_result> {
+    private static class authenticateUser_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<authenticateUser_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, authenticateUser_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -73754,8 +74492,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, authenticateUser_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.success = iprot.readBool();
           struct.setSuccessIsSet(true);
@@ -73773,6 +74511,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class changeUserAuthorizations_args implements org.apache.thrift.TBase<changeUserAuthorizations_args, changeUserAuthorizations_args._Fields>, java.io.Serializable, Cloneable, Comparable<changeUserAuthorizations_args>   {
@@ -73782,15 +74523,12 @@
     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 AUTHORIZATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("authorizations", org.apache.thrift.protocol.TType.SET, (short)3);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new changeUserAuthorizations_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new changeUserAuthorizations_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new changeUserAuthorizations_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new changeUserAuthorizations_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
-    public Set<ByteBuffer> authorizations; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
+    public java.util.Set<java.nio.ByteBuffer> authorizations; // 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 {
@@ -73798,10 +74536,10 @@
       USER((short)2, "user"),
       AUTHORIZATIONS((short)3, "authorizations");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -73828,21 +74566,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -73851,15 +74589,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -73867,7 +74605,7 @@
       tmpMap.put(_Fields.AUTHORIZATIONS, new org.apache.thrift.meta_data.FieldMetaData("authorizations", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
               new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeUserAuthorizations_args.class, metaDataMap);
     }
 
@@ -73875,9 +74613,9 @@
     }
 
     public changeUserAuthorizations_args(
-      ByteBuffer login,
-      String user,
-      Set<ByteBuffer> authorizations)
+      java.nio.ByteBuffer login,
+      java.lang.String user,
+      java.util.Set<java.nio.ByteBuffer> authorizations)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -73896,7 +74634,7 @@
         this.user = other.user;
       }
       if (other.isSetAuthorizations()) {
-        Set<ByteBuffer> __this__authorizations = new HashSet<ByteBuffer>(other.authorizations);
+        java.util.Set<java.nio.ByteBuffer> __this__authorizations = new java.util.HashSet<java.nio.ByteBuffer>(other.authorizations);
         this.authorizations = __this__authorizations;
       }
     }
@@ -73917,16 +74655,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public changeUserAuthorizations_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public changeUserAuthorizations_args setLogin(ByteBuffer login) {
+    public changeUserAuthorizations_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -73946,11 +74684,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public changeUserAuthorizations_args setUser(String user) {
+    public changeUserAuthorizations_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -73974,22 +74712,22 @@
       return (this.authorizations == null) ? 0 : this.authorizations.size();
     }
 
-    public java.util.Iterator<ByteBuffer> getAuthorizationsIterator() {
+    public java.util.Iterator<java.nio.ByteBuffer> getAuthorizationsIterator() {
       return (this.authorizations == null) ? null : this.authorizations.iterator();
     }
 
-    public void addToAuthorizations(ByteBuffer elem) {
+    public void addToAuthorizations(java.nio.ByteBuffer elem) {
       if (this.authorizations == null) {
-        this.authorizations = new HashSet<ByteBuffer>();
+        this.authorizations = new java.util.HashSet<java.nio.ByteBuffer>();
       }
       this.authorizations.add(elem);
     }
 
-    public Set<ByteBuffer> getAuthorizations() {
+    public java.util.Set<java.nio.ByteBuffer> getAuthorizations() {
       return this.authorizations;
     }
 
-    public changeUserAuthorizations_args setAuthorizations(Set<ByteBuffer> authorizations) {
+    public changeUserAuthorizations_args setAuthorizations(java.util.Set<java.nio.ByteBuffer> authorizations) {
       this.authorizations = authorizations;
       return this;
     }
@@ -74009,13 +74747,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -74023,7 +74765,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -74031,14 +74773,14 @@
         if (value == null) {
           unsetAuthorizations();
         } else {
-          setAuthorizations((Set<ByteBuffer>)value);
+          setAuthorizations((java.util.Set<java.nio.ByteBuffer>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -74050,13 +74792,13 @@
         return getAuthorizations();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -74067,11 +74809,11 @@
       case AUTHORIZATIONS:
         return isSetAuthorizations();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof changeUserAuthorizations_args)
@@ -74082,6 +74824,8 @@
     public boolean equals(changeUserAuthorizations_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -74115,24 +74859,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_authorizations = true && (isSetAuthorizations());
-      list.add(present_authorizations);
-      if (present_authorizations)
-        list.add(authorizations);
+      hashCode = hashCode * 8191 + ((isSetAuthorizations()) ? 131071 : 524287);
+      if (isSetAuthorizations())
+        hashCode = hashCode * 8191 + authorizations.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -74143,7 +74884,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -74153,7 +74894,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -74163,7 +74904,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
+      lastComparison = java.lang.Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -74181,16 +74922,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("changeUserAuthorizations_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("changeUserAuthorizations_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -74233,7 +74974,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -74241,13 +74982,13 @@
       }
     }
 
-    private static class changeUserAuthorizations_argsStandardSchemeFactory implements SchemeFactory {
+    private static class changeUserAuthorizations_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public changeUserAuthorizations_argsStandardScheme getScheme() {
         return new changeUserAuthorizations_argsStandardScheme();
       }
     }
 
-    private static class changeUserAuthorizations_argsStandardScheme extends StandardScheme<changeUserAuthorizations_args> {
+    private static class changeUserAuthorizations_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<changeUserAuthorizations_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, changeUserAuthorizations_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -74279,8 +75020,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set418 = iprot.readSetBegin();
-                  struct.authorizations = new HashSet<ByteBuffer>(2*_set418.size);
-                  ByteBuffer _elem419;
+                  struct.authorizations = new java.util.HashSet<java.nio.ByteBuffer>(2*_set418.size);
+                  java.nio.ByteBuffer _elem419;
                   for (int _i420 = 0; _i420 < _set418.size; ++_i420)
                   {
                     _elem419 = iprot.readBinary();
@@ -74322,7 +75063,7 @@
           oprot.writeFieldBegin(AUTHORIZATIONS_FIELD_DESC);
           {
             oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.authorizations.size()));
-            for (ByteBuffer _iter421 : struct.authorizations)
+            for (java.nio.ByteBuffer _iter421 : struct.authorizations)
             {
               oprot.writeBinary(_iter421);
             }
@@ -74336,18 +75077,18 @@
 
     }
 
-    private static class changeUserAuthorizations_argsTupleSchemeFactory implements SchemeFactory {
+    private static class changeUserAuthorizations_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public changeUserAuthorizations_argsTupleScheme getScheme() {
         return new changeUserAuthorizations_argsTupleScheme();
       }
     }
 
-    private static class changeUserAuthorizations_argsTupleScheme extends TupleScheme<changeUserAuthorizations_args> {
+    private static class changeUserAuthorizations_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<changeUserAuthorizations_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, changeUserAuthorizations_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -74367,7 +75108,7 @@
         if (struct.isSetAuthorizations()) {
           {
             oprot.writeI32(struct.authorizations.size());
-            for (ByteBuffer _iter422 : struct.authorizations)
+            for (java.nio.ByteBuffer _iter422 : struct.authorizations)
             {
               oprot.writeBinary(_iter422);
             }
@@ -74377,8 +75118,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, changeUserAuthorizations_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -74390,8 +75131,8 @@
         if (incoming.get(2)) {
           {
             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);
-            ByteBuffer _elem424;
+            struct.authorizations = new java.util.HashSet<java.nio.ByteBuffer>(2*_set423.size);
+            java.nio.ByteBuffer _elem424;
             for (int _i425 = 0; _i425 < _set423.size; ++_i425)
             {
               _elem424 = iprot.readBinary();
@@ -74403,6 +75144,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class changeUserAuthorizations_result implements org.apache.thrift.TBase<changeUserAuthorizations_result, changeUserAuthorizations_result._Fields>, java.io.Serializable, Cloneable, Comparable<changeUserAuthorizations_result>   {
@@ -74411,11 +75155,8 @@
     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 changeUserAuthorizations_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new changeUserAuthorizations_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new changeUserAuthorizations_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new changeUserAuthorizations_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -74425,10 +75166,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -74453,21 +75194,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -74476,20 +75217,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeUserAuthorizations_result.class, metaDataMap);
     }
 
@@ -74575,7 +75316,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -74596,7 +75337,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -74605,13 +75346,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -74620,11 +75361,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof changeUserAuthorizations_result)
@@ -74635,6 +75376,8 @@
     public boolean equals(changeUserAuthorizations_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -74659,19 +75402,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -74682,7 +75423,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -74692,7 +75433,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -74710,16 +75451,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("changeUserAuthorizations_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("changeUserAuthorizations_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -74754,7 +75495,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -74762,13 +75503,13 @@
       }
     }
 
-    private static class changeUserAuthorizations_resultStandardSchemeFactory implements SchemeFactory {
+    private static class changeUserAuthorizations_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public changeUserAuthorizations_resultStandardScheme getScheme() {
         return new changeUserAuthorizations_resultStandardScheme();
       }
     }
 
-    private static class changeUserAuthorizations_resultStandardScheme extends StandardScheme<changeUserAuthorizations_result> {
+    private static class changeUserAuthorizations_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<changeUserAuthorizations_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, changeUserAuthorizations_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -74829,18 +75570,18 @@
 
     }
 
-    private static class changeUserAuthorizations_resultTupleSchemeFactory implements SchemeFactory {
+    private static class changeUserAuthorizations_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public changeUserAuthorizations_resultTupleScheme getScheme() {
         return new changeUserAuthorizations_resultTupleScheme();
       }
     }
 
-    private static class changeUserAuthorizations_resultTupleScheme extends TupleScheme<changeUserAuthorizations_result> {
+    private static class changeUserAuthorizations_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<changeUserAuthorizations_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, changeUserAuthorizations_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -74858,8 +75599,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, changeUserAuthorizations_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -74873,6 +75614,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class changeLocalUserPassword_args implements org.apache.thrift.TBase<changeLocalUserPassword_args, changeLocalUserPassword_args._Fields>, java.io.Serializable, Cloneable, Comparable<changeLocalUserPassword_args>   {
@@ -74882,15 +75626,12 @@
     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 PASSWORD_FIELD_DESC = new org.apache.thrift.protocol.TField("password", 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 changeLocalUserPassword_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new changeLocalUserPassword_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new changeLocalUserPassword_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new changeLocalUserPassword_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
-    public ByteBuffer password; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
+    public java.nio.ByteBuffer password; // 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 {
@@ -74898,10 +75639,10 @@
       USER((short)2, "user"),
       PASSWORD((short)3, "password");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -74928,21 +75669,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -74951,22 +75692,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.PASSWORD, new org.apache.thrift.meta_data.FieldMetaData("password", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeLocalUserPassword_args.class, metaDataMap);
     }
 
@@ -74974,9 +75715,9 @@
     }
 
     public changeLocalUserPassword_args(
-      ByteBuffer login,
-      String user,
-      ByteBuffer password)
+      java.nio.ByteBuffer login,
+      java.lang.String user,
+      java.nio.ByteBuffer password)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -75015,16 +75756,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public changeLocalUserPassword_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public changeLocalUserPassword_args setLogin(ByteBuffer login) {
+    public changeLocalUserPassword_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -75044,11 +75785,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public changeLocalUserPassword_args setUser(String user) {
+    public changeLocalUserPassword_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -75073,16 +75814,16 @@
       return password == null ? null : password.array();
     }
 
-    public ByteBuffer bufferForPassword() {
+    public java.nio.ByteBuffer bufferForPassword() {
       return org.apache.thrift.TBaseHelper.copyBinary(password);
     }
 
     public changeLocalUserPassword_args setPassword(byte[] password) {
-      this.password = password == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(password, password.length));
+      this.password = password == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(password.clone());
       return this;
     }
 
-    public changeLocalUserPassword_args setPassword(ByteBuffer password) {
+    public changeLocalUserPassword_args setPassword(java.nio.ByteBuffer password) {
       this.password = org.apache.thrift.TBaseHelper.copyBinary(password);
       return this;
     }
@@ -75102,13 +75843,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -75116,7 +75861,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -75124,14 +75869,18 @@
         if (value == null) {
           unsetPassword();
         } else {
-          setPassword((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setPassword((byte[])value);
+          } else {
+            setPassword((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -75143,13 +75892,13 @@
         return getPassword();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -75160,11 +75909,11 @@
       case PASSWORD:
         return isSetPassword();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof changeLocalUserPassword_args)
@@ -75175,6 +75924,8 @@
     public boolean equals(changeLocalUserPassword_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -75208,24 +75959,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_password = true && (isSetPassword());
-      list.add(present_password);
-      if (present_password)
-        list.add(password);
+      hashCode = hashCode * 8191 + ((isSetPassword()) ? 131071 : 524287);
+      if (isSetPassword())
+        hashCode = hashCode * 8191 + password.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -75236,7 +75984,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -75246,7 +75994,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -75256,7 +76004,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPassword()).compareTo(other.isSetPassword());
+      lastComparison = java.lang.Boolean.valueOf(isSetPassword()).compareTo(other.isSetPassword());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -75274,16 +76022,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("changeLocalUserPassword_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("changeLocalUserPassword_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -75326,7 +76074,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -75334,13 +76082,13 @@
       }
     }
 
-    private static class changeLocalUserPassword_argsStandardSchemeFactory implements SchemeFactory {
+    private static class changeLocalUserPassword_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public changeLocalUserPassword_argsStandardScheme getScheme() {
         return new changeLocalUserPassword_argsStandardScheme();
       }
     }
 
-    private static class changeLocalUserPassword_argsStandardScheme extends StandardScheme<changeLocalUserPassword_args> {
+    private static class changeLocalUserPassword_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<changeLocalUserPassword_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, changeLocalUserPassword_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -75412,18 +76160,18 @@
 
     }
 
-    private static class changeLocalUserPassword_argsTupleSchemeFactory implements SchemeFactory {
+    private static class changeLocalUserPassword_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public changeLocalUserPassword_argsTupleScheme getScheme() {
         return new changeLocalUserPassword_argsTupleScheme();
       }
     }
 
-    private static class changeLocalUserPassword_argsTupleScheme extends TupleScheme<changeLocalUserPassword_args> {
+    private static class changeLocalUserPassword_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<changeLocalUserPassword_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, changeLocalUserPassword_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -75447,8 +76195,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, changeLocalUserPassword_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -75464,6 +76212,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class changeLocalUserPassword_result implements org.apache.thrift.TBase<changeLocalUserPassword_result, changeLocalUserPassword_result._Fields>, java.io.Serializable, Cloneable, Comparable<changeLocalUserPassword_result>   {
@@ -75472,11 +76223,8 @@
     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 changeLocalUserPassword_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new changeLocalUserPassword_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new changeLocalUserPassword_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new changeLocalUserPassword_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -75486,10 +76234,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -75514,21 +76262,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -75537,20 +76285,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(changeLocalUserPassword_result.class, metaDataMap);
     }
 
@@ -75636,7 +76384,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -75657,7 +76405,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -75666,13 +76414,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -75681,11 +76429,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof changeLocalUserPassword_result)
@@ -75696,6 +76444,8 @@
     public boolean equals(changeLocalUserPassword_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -75720,19 +76470,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -75743,7 +76491,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -75753,7 +76501,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -75771,16 +76519,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("changeLocalUserPassword_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("changeLocalUserPassword_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -75815,7 +76563,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -75823,13 +76571,13 @@
       }
     }
 
-    private static class changeLocalUserPassword_resultStandardSchemeFactory implements SchemeFactory {
+    private static class changeLocalUserPassword_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public changeLocalUserPassword_resultStandardScheme getScheme() {
         return new changeLocalUserPassword_resultStandardScheme();
       }
     }
 
-    private static class changeLocalUserPassword_resultStandardScheme extends StandardScheme<changeLocalUserPassword_result> {
+    private static class changeLocalUserPassword_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<changeLocalUserPassword_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, changeLocalUserPassword_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -75890,18 +76638,18 @@
 
     }
 
-    private static class changeLocalUserPassword_resultTupleSchemeFactory implements SchemeFactory {
+    private static class changeLocalUserPassword_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public changeLocalUserPassword_resultTupleScheme getScheme() {
         return new changeLocalUserPassword_resultTupleScheme();
       }
     }
 
-    private static class changeLocalUserPassword_resultTupleScheme extends TupleScheme<changeLocalUserPassword_result> {
+    private static class changeLocalUserPassword_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<changeLocalUserPassword_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, changeLocalUserPassword_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -75919,8 +76667,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, changeLocalUserPassword_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -75934,6 +76682,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createLocalUser_args implements org.apache.thrift.TBase<createLocalUser_args, createLocalUser_args._Fields>, java.io.Serializable, Cloneable, Comparable<createLocalUser_args>   {
@@ -75943,15 +76694,12 @@
     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 PASSWORD_FIELD_DESC = new org.apache.thrift.protocol.TField("password", 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 createLocalUser_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createLocalUser_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createLocalUser_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createLocalUser_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
-    public ByteBuffer password; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
+    public java.nio.ByteBuffer password; // 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 {
@@ -75959,10 +76707,10 @@
       USER((short)2, "user"),
       PASSWORD((short)3, "password");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -75989,21 +76737,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -76012,22 +76760,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.PASSWORD, new org.apache.thrift.meta_data.FieldMetaData("password", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createLocalUser_args.class, metaDataMap);
     }
 
@@ -76035,9 +76783,9 @@
     }
 
     public createLocalUser_args(
-      ByteBuffer login,
-      String user,
-      ByteBuffer password)
+      java.nio.ByteBuffer login,
+      java.lang.String user,
+      java.nio.ByteBuffer password)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -76076,16 +76824,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createLocalUser_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public createLocalUser_args setLogin(ByteBuffer login) {
+    public createLocalUser_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -76105,11 +76853,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public createLocalUser_args setUser(String user) {
+    public createLocalUser_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -76134,16 +76882,16 @@
       return password == null ? null : password.array();
     }
 
-    public ByteBuffer bufferForPassword() {
+    public java.nio.ByteBuffer bufferForPassword() {
       return org.apache.thrift.TBaseHelper.copyBinary(password);
     }
 
     public createLocalUser_args setPassword(byte[] password) {
-      this.password = password == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(password, password.length));
+      this.password = password == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(password.clone());
       return this;
     }
 
-    public createLocalUser_args setPassword(ByteBuffer password) {
+    public createLocalUser_args setPassword(java.nio.ByteBuffer password) {
       this.password = org.apache.thrift.TBaseHelper.copyBinary(password);
       return this;
     }
@@ -76163,13 +76911,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -76177,7 +76929,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -76185,14 +76937,18 @@
         if (value == null) {
           unsetPassword();
         } else {
-          setPassword((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setPassword((byte[])value);
+          } else {
+            setPassword((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -76204,13 +76960,13 @@
         return getPassword();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -76221,11 +76977,11 @@
       case PASSWORD:
         return isSetPassword();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createLocalUser_args)
@@ -76236,6 +76992,8 @@
     public boolean equals(createLocalUser_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -76269,24 +77027,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_password = true && (isSetPassword());
-      list.add(present_password);
-      if (present_password)
-        list.add(password);
+      hashCode = hashCode * 8191 + ((isSetPassword()) ? 131071 : 524287);
+      if (isSetPassword())
+        hashCode = hashCode * 8191 + password.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -76297,7 +77052,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -76307,7 +77062,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -76317,7 +77072,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPassword()).compareTo(other.isSetPassword());
+      lastComparison = java.lang.Boolean.valueOf(isSetPassword()).compareTo(other.isSetPassword());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -76335,16 +77090,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createLocalUser_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createLocalUser_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -76387,7 +77142,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -76395,13 +77150,13 @@
       }
     }
 
-    private static class createLocalUser_argsStandardSchemeFactory implements SchemeFactory {
+    private static class createLocalUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createLocalUser_argsStandardScheme getScheme() {
         return new createLocalUser_argsStandardScheme();
       }
     }
 
-    private static class createLocalUser_argsStandardScheme extends StandardScheme<createLocalUser_args> {
+    private static class createLocalUser_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createLocalUser_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createLocalUser_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -76473,18 +77228,18 @@
 
     }
 
-    private static class createLocalUser_argsTupleSchemeFactory implements SchemeFactory {
+    private static class createLocalUser_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createLocalUser_argsTupleScheme getScheme() {
         return new createLocalUser_argsTupleScheme();
       }
     }
 
-    private static class createLocalUser_argsTupleScheme extends TupleScheme<createLocalUser_args> {
+    private static class createLocalUser_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createLocalUser_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createLocalUser_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -76508,8 +77263,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createLocalUser_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -76525,6 +77280,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createLocalUser_result implements org.apache.thrift.TBase<createLocalUser_result, createLocalUser_result._Fields>, java.io.Serializable, Cloneable, Comparable<createLocalUser_result>   {
@@ -76533,11 +77291,8 @@
     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 createLocalUser_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createLocalUser_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createLocalUser_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createLocalUser_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -76547,10 +77302,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -76575,21 +77330,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -76598,20 +77353,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createLocalUser_result.class, metaDataMap);
     }
 
@@ -76697,7 +77452,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -76718,7 +77473,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -76727,13 +77482,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -76742,11 +77497,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createLocalUser_result)
@@ -76757,6 +77512,8 @@
     public boolean equals(createLocalUser_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -76781,19 +77538,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -76804,7 +77559,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -76814,7 +77569,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -76832,16 +77587,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createLocalUser_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createLocalUser_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -76876,7 +77631,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -76884,13 +77639,13 @@
       }
     }
 
-    private static class createLocalUser_resultStandardSchemeFactory implements SchemeFactory {
+    private static class createLocalUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createLocalUser_resultStandardScheme getScheme() {
         return new createLocalUser_resultStandardScheme();
       }
     }
 
-    private static class createLocalUser_resultStandardScheme extends StandardScheme<createLocalUser_result> {
+    private static class createLocalUser_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createLocalUser_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createLocalUser_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -76951,18 +77706,18 @@
 
     }
 
-    private static class createLocalUser_resultTupleSchemeFactory implements SchemeFactory {
+    private static class createLocalUser_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createLocalUser_resultTupleScheme getScheme() {
         return new createLocalUser_resultTupleScheme();
       }
     }
 
-    private static class createLocalUser_resultTupleScheme extends TupleScheme<createLocalUser_result> {
+    private static class createLocalUser_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createLocalUser_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createLocalUser_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -76980,8 +77735,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createLocalUser_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -76995,6 +77750,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class dropLocalUser_args implements org.apache.thrift.TBase<dropLocalUser_args, dropLocalUser_args._Fields>, java.io.Serializable, Cloneable, Comparable<dropLocalUser_args>   {
@@ -77003,24 +77761,21 @@
     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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new dropLocalUser_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new dropLocalUser_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new dropLocalUser_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new dropLocalUser_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // 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");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -77045,21 +77800,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -77068,20 +77823,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(dropLocalUser_args.class, metaDataMap);
     }
 
@@ -77089,8 +77844,8 @@
     }
 
     public dropLocalUser_args(
-      ByteBuffer login,
-      String user)
+      java.nio.ByteBuffer login,
+      java.lang.String user)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -77124,16 +77879,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public dropLocalUser_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public dropLocalUser_args setLogin(ByteBuffer login) {
+    public dropLocalUser_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -77153,11 +77908,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public dropLocalUser_args setUser(String user) {
+    public dropLocalUser_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -77177,13 +77932,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -77191,14 +77950,14 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -77207,13 +77966,13 @@
         return getUser();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -77222,11 +77981,11 @@
       case USER:
         return isSetUser();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof dropLocalUser_args)
@@ -77237,6 +77996,8 @@
     public boolean equals(dropLocalUser_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -77261,19 +78022,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -77284,7 +78043,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -77294,7 +78053,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -77312,16 +78071,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("dropLocalUser_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("dropLocalUser_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -77356,7 +78115,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -77364,13 +78123,13 @@
       }
     }
 
-    private static class dropLocalUser_argsStandardSchemeFactory implements SchemeFactory {
+    private static class dropLocalUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public dropLocalUser_argsStandardScheme getScheme() {
         return new dropLocalUser_argsStandardScheme();
       }
     }
 
-    private static class dropLocalUser_argsStandardScheme extends StandardScheme<dropLocalUser_args> {
+    private static class dropLocalUser_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<dropLocalUser_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, dropLocalUser_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -77429,18 +78188,18 @@
 
     }
 
-    private static class dropLocalUser_argsTupleSchemeFactory implements SchemeFactory {
+    private static class dropLocalUser_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public dropLocalUser_argsTupleScheme getScheme() {
         return new dropLocalUser_argsTupleScheme();
       }
     }
 
-    private static class dropLocalUser_argsTupleScheme extends TupleScheme<dropLocalUser_args> {
+    private static class dropLocalUser_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<dropLocalUser_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, dropLocalUser_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -77458,8 +78217,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, dropLocalUser_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -77471,6 +78230,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class dropLocalUser_result implements org.apache.thrift.TBase<dropLocalUser_result, dropLocalUser_result._Fields>, java.io.Serializable, Cloneable, Comparable<dropLocalUser_result>   {
@@ -77479,11 +78241,8 @@
     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 dropLocalUser_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new dropLocalUser_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new dropLocalUser_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new dropLocalUser_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -77493,10 +78252,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -77521,21 +78280,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -77544,20 +78303,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(dropLocalUser_result.class, metaDataMap);
     }
 
@@ -77643,7 +78402,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -77664,7 +78423,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -77673,13 +78432,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -77688,11 +78447,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof dropLocalUser_result)
@@ -77703,6 +78462,8 @@
     public boolean equals(dropLocalUser_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -77727,19 +78488,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -77750,7 +78509,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -77760,7 +78519,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -77778,16 +78537,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("dropLocalUser_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("dropLocalUser_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -77822,7 +78581,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -77830,13 +78589,13 @@
       }
     }
 
-    private static class dropLocalUser_resultStandardSchemeFactory implements SchemeFactory {
+    private static class dropLocalUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public dropLocalUser_resultStandardScheme getScheme() {
         return new dropLocalUser_resultStandardScheme();
       }
     }
 
-    private static class dropLocalUser_resultStandardScheme extends StandardScheme<dropLocalUser_result> {
+    private static class dropLocalUser_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<dropLocalUser_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, dropLocalUser_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -77897,18 +78656,18 @@
 
     }
 
-    private static class dropLocalUser_resultTupleSchemeFactory implements SchemeFactory {
+    private static class dropLocalUser_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public dropLocalUser_resultTupleScheme getScheme() {
         return new dropLocalUser_resultTupleScheme();
       }
     }
 
-    private static class dropLocalUser_resultTupleScheme extends TupleScheme<dropLocalUser_result> {
+    private static class dropLocalUser_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<dropLocalUser_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, dropLocalUser_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -77926,8 +78685,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, dropLocalUser_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -77941,6 +78700,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getUserAuthorizations_args implements org.apache.thrift.TBase<getUserAuthorizations_args, getUserAuthorizations_args._Fields>, java.io.Serializable, Cloneable, Comparable<getUserAuthorizations_args>   {
@@ -77949,24 +78711,21 @@
     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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new getUserAuthorizations_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getUserAuthorizations_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getUserAuthorizations_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getUserAuthorizations_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // 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");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -77991,21 +78750,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -78014,20 +78773,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUserAuthorizations_args.class, metaDataMap);
     }
 
@@ -78035,8 +78794,8 @@
     }
 
     public getUserAuthorizations_args(
-      ByteBuffer login,
-      String user)
+      java.nio.ByteBuffer login,
+      java.lang.String user)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -78070,16 +78829,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public getUserAuthorizations_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getUserAuthorizations_args setLogin(ByteBuffer login) {
+    public getUserAuthorizations_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -78099,11 +78858,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public getUserAuthorizations_args setUser(String user) {
+    public getUserAuthorizations_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -78123,13 +78882,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -78137,14 +78900,14 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -78153,13 +78916,13 @@
         return getUser();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -78168,11 +78931,11 @@
       case USER:
         return isSetUser();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getUserAuthorizations_args)
@@ -78183,6 +78946,8 @@
     public boolean equals(getUserAuthorizations_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -78207,19 +78972,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -78230,7 +78993,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -78240,7 +79003,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -78258,16 +79021,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getUserAuthorizations_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getUserAuthorizations_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -78302,7 +79065,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -78310,13 +79073,13 @@
       }
     }
 
-    private static class getUserAuthorizations_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getUserAuthorizations_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getUserAuthorizations_argsStandardScheme getScheme() {
         return new getUserAuthorizations_argsStandardScheme();
       }
     }
 
-    private static class getUserAuthorizations_argsStandardScheme extends StandardScheme<getUserAuthorizations_args> {
+    private static class getUserAuthorizations_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getUserAuthorizations_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getUserAuthorizations_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -78375,18 +79138,18 @@
 
     }
 
-    private static class getUserAuthorizations_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getUserAuthorizations_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getUserAuthorizations_argsTupleScheme getScheme() {
         return new getUserAuthorizations_argsTupleScheme();
       }
     }
 
-    private static class getUserAuthorizations_argsTupleScheme extends TupleScheme<getUserAuthorizations_args> {
+    private static class getUserAuthorizations_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getUserAuthorizations_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getUserAuthorizations_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -78404,8 +79167,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getUserAuthorizations_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -78417,6 +79180,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getUserAuthorizations_result implements org.apache.thrift.TBase<getUserAuthorizations_result, getUserAuthorizations_result._Fields>, java.io.Serializable, Cloneable, Comparable<getUserAuthorizations_result>   {
@@ -78426,13 +79192,10 @@
     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 getUserAuthorizations_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getUserAuthorizations_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getUserAuthorizations_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getUserAuthorizations_resultTupleSchemeFactory();
 
-    public List<ByteBuffer> success; // required
+    public java.util.List<java.nio.ByteBuffer> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
 
@@ -78442,10 +79205,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -78472,21 +79235,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -78495,23 +79258,23 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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              , true))));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUserAuthorizations_result.class, metaDataMap);
     }
 
@@ -78519,7 +79282,7 @@
     }
 
     public getUserAuthorizations_result(
-      List<ByteBuffer> success,
+      java.util.List<java.nio.ByteBuffer> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2)
     {
@@ -78534,7 +79297,7 @@
      */
     public getUserAuthorizations_result(getUserAuthorizations_result other) {
       if (other.isSetSuccess()) {
-        List<ByteBuffer> __this__success = new ArrayList<ByteBuffer>(other.success);
+        java.util.List<java.nio.ByteBuffer> __this__success = new java.util.ArrayList<java.nio.ByteBuffer>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -78560,22 +79323,22 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public java.util.Iterator<ByteBuffer> getSuccessIterator() {
+    public java.util.Iterator<java.nio.ByteBuffer> getSuccessIterator() {
       return (this.success == null) ? null : this.success.iterator();
     }
 
-    public void addToSuccess(ByteBuffer elem) {
+    public void addToSuccess(java.nio.ByteBuffer elem) {
       if (this.success == null) {
-        this.success = new ArrayList<ByteBuffer>();
+        this.success = new java.util.ArrayList<java.nio.ByteBuffer>();
       }
       this.success.add(elem);
     }
 
-    public List<ByteBuffer> getSuccess() {
+    public java.util.List<java.nio.ByteBuffer> getSuccess() {
       return this.success;
     }
 
-    public getUserAuthorizations_result setSuccess(List<ByteBuffer> success) {
+    public getUserAuthorizations_result setSuccess(java.util.List<java.nio.ByteBuffer> success) {
       this.success = success;
       return this;
     }
@@ -78643,13 +79406,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((List<ByteBuffer>)value);
+          setSuccess((java.util.List<java.nio.ByteBuffer>)value);
         }
         break;
 
@@ -78672,7 +79435,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -78684,13 +79447,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -78701,11 +79464,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getUserAuthorizations_result)
@@ -78716,6 +79479,8 @@
     public boolean equals(getUserAuthorizations_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -78749,24 +79514,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -78777,7 +79539,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -78787,7 +79549,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -78797,7 +79559,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -78815,16 +79577,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getUserAuthorizations_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getUserAuthorizations_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -78867,7 +79629,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -78875,13 +79637,13 @@
       }
     }
 
-    private static class getUserAuthorizations_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getUserAuthorizations_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getUserAuthorizations_resultStandardScheme getScheme() {
         return new getUserAuthorizations_resultStandardScheme();
       }
     }
 
-    private static class getUserAuthorizations_resultStandardScheme extends StandardScheme<getUserAuthorizations_result> {
+    private static class getUserAuthorizations_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getUserAuthorizations_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getUserAuthorizations_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -78897,8 +79659,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                 {
                   org.apache.thrift.protocol.TList _list426 = iprot.readListBegin();
-                  struct.success = new ArrayList<ByteBuffer>(_list426.size);
-                  ByteBuffer _elem427;
+                  struct.success = new java.util.ArrayList<java.nio.ByteBuffer>(_list426.size);
+                  java.nio.ByteBuffer _elem427;
                   for (int _i428 = 0; _i428 < _list426.size; ++_i428)
                   {
                     _elem427 = iprot.readBinary();
@@ -78948,7 +79710,7 @@
           oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
           {
             oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
-            for (ByteBuffer _iter429 : struct.success)
+            for (java.nio.ByteBuffer _iter429 : struct.success)
             {
               oprot.writeBinary(_iter429);
             }
@@ -78972,18 +79734,18 @@
 
     }
 
-    private static class getUserAuthorizations_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getUserAuthorizations_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getUserAuthorizations_resultTupleScheme getScheme() {
         return new getUserAuthorizations_resultTupleScheme();
       }
     }
 
-    private static class getUserAuthorizations_resultTupleScheme extends TupleScheme<getUserAuthorizations_result> {
+    private static class getUserAuthorizations_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getUserAuthorizations_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getUserAuthorizations_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -78997,7 +79759,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (ByteBuffer _iter430 : struct.success)
+            for (java.nio.ByteBuffer _iter430 : struct.success)
             {
               oprot.writeBinary(_iter430);
             }
@@ -79013,13 +79775,13 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getUserAuthorizations_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           {
             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);
-            ByteBuffer _elem432;
+            struct.success = new java.util.ArrayList<java.nio.ByteBuffer>(_list431.size);
+            java.nio.ByteBuffer _elem432;
             for (int _i433 = 0; _i433 < _list431.size; ++_i433)
             {
               _elem432 = iprot.readBinary();
@@ -79041,6 +79803,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class grantSystemPermission_args implements org.apache.thrift.TBase<grantSystemPermission_args, grantSystemPermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<grantSystemPermission_args>   {
@@ -79050,14 +79815,11 @@
     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 PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", 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 grantSystemPermission_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new grantSystemPermission_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new grantSystemPermission_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new grantSystemPermission_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
     /**
      * 
      * @see SystemPermission
@@ -79074,10 +79836,10 @@
        */
       PERM((short)3, "perm");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -79104,21 +79866,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -79127,22 +79889,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.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, SystemPermission.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantSystemPermission_args.class, metaDataMap);
     }
 
@@ -79150,8 +79912,8 @@
     }
 
     public grantSystemPermission_args(
-      ByteBuffer login,
-      String user,
+      java.nio.ByteBuffer login,
+      java.lang.String user,
       SystemPermission perm)
     {
       this();
@@ -79191,16 +79953,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public grantSystemPermission_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public grantSystemPermission_args setLogin(ByteBuffer login) {
+    public grantSystemPermission_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -79220,11 +79982,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public grantSystemPermission_args setUser(String user) {
+    public grantSystemPermission_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -79276,13 +80038,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -79290,7 +80056,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -79305,7 +80071,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -79317,13 +80083,13 @@
         return getPerm();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -79334,11 +80100,11 @@
       case PERM:
         return isSetPerm();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof grantSystemPermission_args)
@@ -79349,6 +80115,8 @@
     public boolean equals(grantSystemPermission_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -79382,24 +80150,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_perm = true && (isSetPerm());
-      list.add(present_perm);
-      if (present_perm)
-        list.add(perm.getValue());
+      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
+      if (isSetPerm())
+        hashCode = hashCode * 8191 + perm.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -79410,7 +80175,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -79420,7 +80185,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -79430,7 +80195,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -79448,16 +80213,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("grantSystemPermission_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantSystemPermission_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -79500,7 +80265,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -79508,13 +80273,13 @@
       }
     }
 
-    private static class grantSystemPermission_argsStandardSchemeFactory implements SchemeFactory {
+    private static class grantSystemPermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantSystemPermission_argsStandardScheme getScheme() {
         return new grantSystemPermission_argsStandardScheme();
       }
     }
 
-    private static class grantSystemPermission_argsStandardScheme extends StandardScheme<grantSystemPermission_args> {
+    private static class grantSystemPermission_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<grantSystemPermission_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, grantSystemPermission_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -79586,18 +80351,18 @@
 
     }
 
-    private static class grantSystemPermission_argsTupleSchemeFactory implements SchemeFactory {
+    private static class grantSystemPermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantSystemPermission_argsTupleScheme getScheme() {
         return new grantSystemPermission_argsTupleScheme();
       }
     }
 
-    private static class grantSystemPermission_argsTupleScheme extends TupleScheme<grantSystemPermission_args> {
+    private static class grantSystemPermission_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<grantSystemPermission_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, grantSystemPermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -79621,8 +80386,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, grantSystemPermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -79638,6 +80403,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class grantSystemPermission_result implements org.apache.thrift.TBase<grantSystemPermission_result, grantSystemPermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<grantSystemPermission_result>   {
@@ -79646,11 +80414,8 @@
     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 grantSystemPermission_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new grantSystemPermission_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new grantSystemPermission_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new grantSystemPermission_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -79660,10 +80425,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -79688,21 +80453,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -79711,20 +80476,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantSystemPermission_result.class, metaDataMap);
     }
 
@@ -79810,7 +80575,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -79831,7 +80596,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -79840,13 +80605,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -79855,11 +80620,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof grantSystemPermission_result)
@@ -79870,6 +80635,8 @@
     public boolean equals(grantSystemPermission_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -79894,19 +80661,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -79917,7 +80682,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -79927,7 +80692,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -79945,16 +80710,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("grantSystemPermission_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantSystemPermission_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -79989,7 +80754,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -79997,13 +80762,13 @@
       }
     }
 
-    private static class grantSystemPermission_resultStandardSchemeFactory implements SchemeFactory {
+    private static class grantSystemPermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantSystemPermission_resultStandardScheme getScheme() {
         return new grantSystemPermission_resultStandardScheme();
       }
     }
 
-    private static class grantSystemPermission_resultStandardScheme extends StandardScheme<grantSystemPermission_result> {
+    private static class grantSystemPermission_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<grantSystemPermission_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, grantSystemPermission_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -80064,18 +80829,18 @@
 
     }
 
-    private static class grantSystemPermission_resultTupleSchemeFactory implements SchemeFactory {
+    private static class grantSystemPermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantSystemPermission_resultTupleScheme getScheme() {
         return new grantSystemPermission_resultTupleScheme();
       }
     }
 
-    private static class grantSystemPermission_resultTupleScheme extends TupleScheme<grantSystemPermission_result> {
+    private static class grantSystemPermission_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<grantSystemPermission_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, grantSystemPermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -80093,8 +80858,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, grantSystemPermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -80108,6 +80873,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class grantTablePermission_args implements org.apache.thrift.TBase<grantTablePermission_args, grantTablePermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<grantTablePermission_args>   {
@@ -80118,15 +80886,12 @@
     private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", 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 grantTablePermission_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new grantTablePermission_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new grantTablePermission_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new grantTablePermission_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
-    public String table; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
+    public java.lang.String table; // required
     /**
      * 
      * @see TablePermission
@@ -80144,10 +80909,10 @@
        */
       PERM((short)4, "perm");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -80176,21 +80941,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -80199,15 +80964,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -80216,7 +80981,7 @@
           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, TablePermission.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantTablePermission_args.class, metaDataMap);
     }
 
@@ -80224,9 +80989,9 @@
     }
 
     public grantTablePermission_args(
-      ByteBuffer login,
-      String user,
-      String table,
+      java.nio.ByteBuffer login,
+      java.lang.String user,
+      java.lang.String table,
       TablePermission perm)
     {
       this();
@@ -80271,16 +81036,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public grantTablePermission_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public grantTablePermission_args setLogin(ByteBuffer login) {
+    public grantTablePermission_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -80300,11 +81065,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public grantTablePermission_args setUser(String user) {
+    public grantTablePermission_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -80324,11 +81089,11 @@
       }
     }
 
-    public String getTable() {
+    public java.lang.String getTable() {
       return this.table;
     }
 
-    public grantTablePermission_args setTable(String table) {
+    public grantTablePermission_args setTable(java.lang.String table) {
       this.table = table;
       return this;
     }
@@ -80380,13 +81145,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -80394,7 +81163,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -80402,7 +81171,7 @@
         if (value == null) {
           unsetTable();
         } else {
-          setTable((String)value);
+          setTable((java.lang.String)value);
         }
         break;
 
@@ -80417,7 +81186,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -80432,13 +81201,13 @@
         return getPerm();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -80451,11 +81220,11 @@
       case PERM:
         return isSetPerm();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof grantTablePermission_args)
@@ -80466,6 +81235,8 @@
     public boolean equals(grantTablePermission_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -80508,29 +81279,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_table = true && (isSetTable());
-      list.add(present_table);
-      if (present_table)
-        list.add(table);
+      hashCode = hashCode * 8191 + ((isSetTable()) ? 131071 : 524287);
+      if (isSetTable())
+        hashCode = hashCode * 8191 + table.hashCode();
 
-      boolean present_perm = true && (isSetPerm());
-      list.add(present_perm);
-      if (present_perm)
-        list.add(perm.getValue());
+      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
+      if (isSetPerm())
+        hashCode = hashCode * 8191 + perm.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -80541,7 +81308,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -80551,7 +81318,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -80561,7 +81328,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
+      lastComparison = java.lang.Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -80571,7 +81338,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -80589,16 +81356,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("grantTablePermission_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantTablePermission_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -80649,7 +81416,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -80657,13 +81424,13 @@
       }
     }
 
-    private static class grantTablePermission_argsStandardSchemeFactory implements SchemeFactory {
+    private static class grantTablePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantTablePermission_argsStandardScheme getScheme() {
         return new grantTablePermission_argsStandardScheme();
       }
     }
 
-    private static class grantTablePermission_argsStandardScheme extends StandardScheme<grantTablePermission_args> {
+    private static class grantTablePermission_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<grantTablePermission_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, grantTablePermission_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -80748,18 +81515,18 @@
 
     }
 
-    private static class grantTablePermission_argsTupleSchemeFactory implements SchemeFactory {
+    private static class grantTablePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantTablePermission_argsTupleScheme getScheme() {
         return new grantTablePermission_argsTupleScheme();
       }
     }
 
-    private static class grantTablePermission_argsTupleScheme extends TupleScheme<grantTablePermission_args> {
+    private static class grantTablePermission_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<grantTablePermission_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, grantTablePermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -80789,8 +81556,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, grantTablePermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -80810,6 +81577,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class grantTablePermission_result implements org.apache.thrift.TBase<grantTablePermission_result, grantTablePermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<grantTablePermission_result>   {
@@ -80819,11 +81589,8 @@
     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 grantTablePermission_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new grantTablePermission_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new grantTablePermission_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new grantTablePermission_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -80835,10 +81602,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -80865,21 +81632,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -80888,22 +81655,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantTablePermission_result.class, metaDataMap);
     }
 
@@ -81019,7 +81786,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -81048,7 +81815,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -81060,13 +81827,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -81077,11 +81844,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof grantTablePermission_result)
@@ -81092,6 +81859,8 @@
     public boolean equals(grantTablePermission_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -81125,24 +81894,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -81153,7 +81919,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -81163,7 +81929,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -81173,7 +81939,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -81191,16 +81957,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("grantTablePermission_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantTablePermission_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -81243,7 +82009,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -81251,13 +82017,13 @@
       }
     }
 
-    private static class grantTablePermission_resultStandardSchemeFactory implements SchemeFactory {
+    private static class grantTablePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantTablePermission_resultStandardScheme getScheme() {
         return new grantTablePermission_resultStandardScheme();
       }
     }
 
-    private static class grantTablePermission_resultStandardScheme extends StandardScheme<grantTablePermission_result> {
+    private static class grantTablePermission_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<grantTablePermission_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, grantTablePermission_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -81332,18 +82098,18 @@
 
     }
 
-    private static class grantTablePermission_resultTupleSchemeFactory implements SchemeFactory {
+    private static class grantTablePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantTablePermission_resultTupleScheme getScheme() {
         return new grantTablePermission_resultTupleScheme();
       }
     }
 
-    private static class grantTablePermission_resultTupleScheme extends TupleScheme<grantTablePermission_result> {
+    private static class grantTablePermission_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<grantTablePermission_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, grantTablePermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -81367,8 +82133,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, grantTablePermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -81387,6 +82153,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class hasSystemPermission_args implements org.apache.thrift.TBase<hasSystemPermission_args, hasSystemPermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<hasSystemPermission_args>   {
@@ -81396,14 +82165,11 @@
     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 PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", 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 hasSystemPermission_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new hasSystemPermission_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasSystemPermission_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasSystemPermission_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
     /**
      * 
      * @see SystemPermission
@@ -81420,10 +82186,10 @@
        */
       PERM((short)3, "perm");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -81450,21 +82216,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -81473,22 +82239,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.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, SystemPermission.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasSystemPermission_args.class, metaDataMap);
     }
 
@@ -81496,8 +82262,8 @@
     }
 
     public hasSystemPermission_args(
-      ByteBuffer login,
-      String user,
+      java.nio.ByteBuffer login,
+      java.lang.String user,
       SystemPermission perm)
     {
       this();
@@ -81537,16 +82303,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public hasSystemPermission_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public hasSystemPermission_args setLogin(ByteBuffer login) {
+    public hasSystemPermission_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -81566,11 +82332,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public hasSystemPermission_args setUser(String user) {
+    public hasSystemPermission_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -81622,13 +82388,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -81636,7 +82406,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -81651,7 +82421,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -81663,13 +82433,13 @@
         return getPerm();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -81680,11 +82450,11 @@
       case PERM:
         return isSetPerm();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof hasSystemPermission_args)
@@ -81695,6 +82465,8 @@
     public boolean equals(hasSystemPermission_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -81728,24 +82500,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_perm = true && (isSetPerm());
-      list.add(present_perm);
-      if (present_perm)
-        list.add(perm.getValue());
+      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
+      if (isSetPerm())
+        hashCode = hashCode * 8191 + perm.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -81756,7 +82525,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -81766,7 +82535,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -81776,7 +82545,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -81794,16 +82563,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("hasSystemPermission_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasSystemPermission_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -81846,7 +82615,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -81854,13 +82623,13 @@
       }
     }
 
-    private static class hasSystemPermission_argsStandardSchemeFactory implements SchemeFactory {
+    private static class hasSystemPermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasSystemPermission_argsStandardScheme getScheme() {
         return new hasSystemPermission_argsStandardScheme();
       }
     }
 
-    private static class hasSystemPermission_argsStandardScheme extends StandardScheme<hasSystemPermission_args> {
+    private static class hasSystemPermission_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<hasSystemPermission_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, hasSystemPermission_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -81932,18 +82701,18 @@
 
     }
 
-    private static class hasSystemPermission_argsTupleSchemeFactory implements SchemeFactory {
+    private static class hasSystemPermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasSystemPermission_argsTupleScheme getScheme() {
         return new hasSystemPermission_argsTupleScheme();
       }
     }
 
-    private static class hasSystemPermission_argsTupleScheme extends TupleScheme<hasSystemPermission_args> {
+    private static class hasSystemPermission_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<hasSystemPermission_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, hasSystemPermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -81967,8 +82736,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, hasSystemPermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -81984,6 +82753,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class hasSystemPermission_result implements org.apache.thrift.TBase<hasSystemPermission_result, hasSystemPermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<hasSystemPermission_result>   {
@@ -81993,11 +82765,8 @@
     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 hasSystemPermission_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new hasSystemPermission_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasSystemPermission_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasSystemPermission_resultTupleSchemeFactory();
 
     public boolean success; // required
     public AccumuloException ouch1; // required
@@ -82009,10 +82778,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -82039,21 +82808,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -82062,7 +82831,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -82070,16 +82839,16 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasSystemPermission_result.class, metaDataMap);
     }
 
@@ -82135,16 +82904,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public AccumuloException getOuch1() {
@@ -82195,13 +82964,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Boolean)value);
+          setSuccess((java.lang.Boolean)value);
         }
         break;
 
@@ -82224,7 +82993,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return isSuccess();
@@ -82236,13 +83005,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -82253,11 +83022,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof hasSystemPermission_result)
@@ -82268,6 +83037,8 @@
     public boolean equals(hasSystemPermission_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -82301,24 +83072,19 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -82329,7 +83095,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -82339,7 +83105,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -82349,7 +83115,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -82367,16 +83133,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("hasSystemPermission_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasSystemPermission_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -82415,7 +83181,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -82425,13 +83191,13 @@
       }
     }
 
-    private static class hasSystemPermission_resultStandardSchemeFactory implements SchemeFactory {
+    private static class hasSystemPermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasSystemPermission_resultStandardScheme getScheme() {
         return new hasSystemPermission_resultStandardScheme();
       }
     }
 
-    private static class hasSystemPermission_resultStandardScheme extends StandardScheme<hasSystemPermission_result> {
+    private static class hasSystemPermission_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<hasSystemPermission_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, hasSystemPermission_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -82505,18 +83271,18 @@
 
     }
 
-    private static class hasSystemPermission_resultTupleSchemeFactory implements SchemeFactory {
+    private static class hasSystemPermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasSystemPermission_resultTupleScheme getScheme() {
         return new hasSystemPermission_resultTupleScheme();
       }
     }
 
-    private static class hasSystemPermission_resultTupleScheme extends TupleScheme<hasSystemPermission_result> {
+    private static class hasSystemPermission_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<hasSystemPermission_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, hasSystemPermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -82540,8 +83306,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, hasSystemPermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.success = iprot.readBool();
           struct.setSuccessIsSet(true);
@@ -82559,6 +83325,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class hasTablePermission_args implements org.apache.thrift.TBase<hasTablePermission_args, hasTablePermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<hasTablePermission_args>   {
@@ -82569,15 +83338,12 @@
     private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", 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 hasTablePermission_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new hasTablePermission_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasTablePermission_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasTablePermission_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
-    public String table; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
+    public java.lang.String table; // required
     /**
      * 
      * @see TablePermission
@@ -82595,10 +83361,10 @@
        */
       PERM((short)4, "perm");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -82627,21 +83393,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -82650,15 +83416,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -82667,7 +83433,7 @@
           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, TablePermission.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasTablePermission_args.class, metaDataMap);
     }
 
@@ -82675,9 +83441,9 @@
     }
 
     public hasTablePermission_args(
-      ByteBuffer login,
-      String user,
-      String table,
+      java.nio.ByteBuffer login,
+      java.lang.String user,
+      java.lang.String table,
       TablePermission perm)
     {
       this();
@@ -82722,16 +83488,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public hasTablePermission_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public hasTablePermission_args setLogin(ByteBuffer login) {
+    public hasTablePermission_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -82751,11 +83517,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public hasTablePermission_args setUser(String user) {
+    public hasTablePermission_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -82775,11 +83541,11 @@
       }
     }
 
-    public String getTable() {
+    public java.lang.String getTable() {
       return this.table;
     }
 
-    public hasTablePermission_args setTable(String table) {
+    public hasTablePermission_args setTable(java.lang.String table) {
       this.table = table;
       return this;
     }
@@ -82831,13 +83597,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -82845,7 +83615,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -82853,7 +83623,7 @@
         if (value == null) {
           unsetTable();
         } else {
-          setTable((String)value);
+          setTable((java.lang.String)value);
         }
         break;
 
@@ -82868,7 +83638,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -82883,13 +83653,13 @@
         return getPerm();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -82902,11 +83672,11 @@
       case PERM:
         return isSetPerm();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof hasTablePermission_args)
@@ -82917,6 +83687,8 @@
     public boolean equals(hasTablePermission_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -82959,29 +83731,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_table = true && (isSetTable());
-      list.add(present_table);
-      if (present_table)
-        list.add(table);
+      hashCode = hashCode * 8191 + ((isSetTable()) ? 131071 : 524287);
+      if (isSetTable())
+        hashCode = hashCode * 8191 + table.hashCode();
 
-      boolean present_perm = true && (isSetPerm());
-      list.add(present_perm);
-      if (present_perm)
-        list.add(perm.getValue());
+      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
+      if (isSetPerm())
+        hashCode = hashCode * 8191 + perm.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -82992,7 +83760,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -83002,7 +83770,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -83012,7 +83780,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
+      lastComparison = java.lang.Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -83022,7 +83790,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -83040,16 +83808,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("hasTablePermission_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasTablePermission_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -83100,7 +83868,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -83108,13 +83876,13 @@
       }
     }
 
-    private static class hasTablePermission_argsStandardSchemeFactory implements SchemeFactory {
+    private static class hasTablePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasTablePermission_argsStandardScheme getScheme() {
         return new hasTablePermission_argsStandardScheme();
       }
     }
 
-    private static class hasTablePermission_argsStandardScheme extends StandardScheme<hasTablePermission_args> {
+    private static class hasTablePermission_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<hasTablePermission_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, hasTablePermission_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -83199,18 +83967,18 @@
 
     }
 
-    private static class hasTablePermission_argsTupleSchemeFactory implements SchemeFactory {
+    private static class hasTablePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasTablePermission_argsTupleScheme getScheme() {
         return new hasTablePermission_argsTupleScheme();
       }
     }
 
-    private static class hasTablePermission_argsTupleScheme extends TupleScheme<hasTablePermission_args> {
+    private static class hasTablePermission_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<hasTablePermission_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, hasTablePermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -83240,8 +84008,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, hasTablePermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -83261,6 +84029,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class hasTablePermission_result implements org.apache.thrift.TBase<hasTablePermission_result, hasTablePermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<hasTablePermission_result>   {
@@ -83271,11 +84042,8 @@
     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 hasTablePermission_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new hasTablePermission_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasTablePermission_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasTablePermission_resultTupleSchemeFactory();
 
     public boolean success; // required
     public AccumuloException ouch1; // required
@@ -83289,10 +84057,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -83321,21 +84089,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -83344,7 +84112,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -83352,18 +84120,18 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasTablePermission_result.class, metaDataMap);
     }
 
@@ -83425,16 +84193,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public AccumuloException getOuch1() {
@@ -83509,13 +84277,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Boolean)value);
+          setSuccess((java.lang.Boolean)value);
         }
         break;
 
@@ -83546,7 +84314,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return isSuccess();
@@ -83561,13 +84329,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -83580,11 +84348,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof hasTablePermission_result)
@@ -83595,6 +84363,8 @@
     public boolean equals(hasTablePermission_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -83637,29 +84407,23 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -83670,7 +84434,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -83680,7 +84444,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -83690,7 +84454,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -83700,7 +84464,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -83718,16 +84482,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("hasTablePermission_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasTablePermission_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -83774,7 +84538,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -83784,13 +84548,13 @@
       }
     }
 
-    private static class hasTablePermission_resultStandardSchemeFactory implements SchemeFactory {
+    private static class hasTablePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasTablePermission_resultStandardScheme getScheme() {
         return new hasTablePermission_resultStandardScheme();
       }
     }
 
-    private static class hasTablePermission_resultStandardScheme extends StandardScheme<hasTablePermission_result> {
+    private static class hasTablePermission_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<hasTablePermission_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, hasTablePermission_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -83878,18 +84642,18 @@
 
     }
 
-    private static class hasTablePermission_resultTupleSchemeFactory implements SchemeFactory {
+    private static class hasTablePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasTablePermission_resultTupleScheme getScheme() {
         return new hasTablePermission_resultTupleScheme();
       }
     }
 
-    private static class hasTablePermission_resultTupleScheme extends TupleScheme<hasTablePermission_result> {
+    private static class hasTablePermission_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<hasTablePermission_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, hasTablePermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -83919,8 +84683,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, hasTablePermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = iprot.readBool();
           struct.setSuccessIsSet(true);
@@ -83943,6 +84707,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listLocalUsers_args implements org.apache.thrift.TBase<listLocalUsers_args, listLocalUsers_args._Fields>, java.io.Serializable, Cloneable, Comparable<listLocalUsers_args>   {
@@ -83950,22 +84717,19 @@
 
     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 listLocalUsers_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new listLocalUsers_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listLocalUsers_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listLocalUsers_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
+    public java.nio.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -83988,21 +84752,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -84011,18 +84775,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listLocalUsers_args.class, metaDataMap);
     }
 
@@ -84030,7 +84794,7 @@
     }
 
     public listLocalUsers_args(
-      ByteBuffer login)
+      java.nio.ByteBuffer login)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -84059,16 +84823,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public listLocalUsers_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public listLocalUsers_args setLogin(ByteBuffer login) {
+    public listLocalUsers_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -84088,43 +84852,47 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case LOGIN:
         return isSetLogin();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listLocalUsers_args)
@@ -84135,6 +84903,8 @@
     public boolean equals(listLocalUsers_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -84150,14 +84920,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -84168,7 +84937,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -84186,16 +84955,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listLocalUsers_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listLocalUsers_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -84222,7 +84991,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -84230,13 +84999,13 @@
       }
     }
 
-    private static class listLocalUsers_argsStandardSchemeFactory implements SchemeFactory {
+    private static class listLocalUsers_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listLocalUsers_argsStandardScheme getScheme() {
         return new listLocalUsers_argsStandardScheme();
       }
     }
 
-    private static class listLocalUsers_argsStandardScheme extends StandardScheme<listLocalUsers_args> {
+    private static class listLocalUsers_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<listLocalUsers_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, listLocalUsers_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -84282,18 +85051,18 @@
 
     }
 
-    private static class listLocalUsers_argsTupleSchemeFactory implements SchemeFactory {
+    private static class listLocalUsers_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listLocalUsers_argsTupleScheme getScheme() {
         return new listLocalUsers_argsTupleScheme();
       }
     }
 
-    private static class listLocalUsers_argsTupleScheme extends TupleScheme<listLocalUsers_args> {
+    private static class listLocalUsers_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<listLocalUsers_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, listLocalUsers_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -84305,8 +85074,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, listLocalUsers_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -84314,6 +85083,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listLocalUsers_result implements org.apache.thrift.TBase<listLocalUsers_result, listLocalUsers_result._Fields>, java.io.Serializable, Cloneable, Comparable<listLocalUsers_result>   {
@@ -84324,13 +85096,10 @@
     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 listLocalUsers_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new listLocalUsers_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listLocalUsers_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listLocalUsers_resultTupleSchemeFactory();
 
-    public Set<String> success; // required
+    public java.util.Set<java.lang.String> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -84342,10 +85111,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -84374,21 +85143,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -84397,25 +85166,25 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.SetMetaData(org.apache.thrift.protocol.TType.SET, 
               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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listLocalUsers_result.class, metaDataMap);
     }
 
@@ -84423,7 +85192,7 @@
     }
 
     public listLocalUsers_result(
-      Set<String> success,
+      java.util.Set<java.lang.String> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -84440,7 +85209,7 @@
      */
     public listLocalUsers_result(listLocalUsers_result other) {
       if (other.isSetSuccess()) {
-        Set<String> __this__success = new HashSet<String>(other.success);
+        java.util.Set<java.lang.String> __this__success = new java.util.HashSet<java.lang.String>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -84470,22 +85239,22 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public java.util.Iterator<String> getSuccessIterator() {
+    public java.util.Iterator<java.lang.String> getSuccessIterator() {
       return (this.success == null) ? null : this.success.iterator();
     }
 
-    public void addToSuccess(String elem) {
+    public void addToSuccess(java.lang.String elem) {
       if (this.success == null) {
-        this.success = new HashSet<String>();
+        this.success = new java.util.HashSet<java.lang.String>();
       }
       this.success.add(elem);
     }
 
-    public Set<String> getSuccess() {
+    public java.util.Set<java.lang.String> getSuccess() {
       return this.success;
     }
 
-    public listLocalUsers_result setSuccess(Set<String> success) {
+    public listLocalUsers_result setSuccess(java.util.Set<java.lang.String> success) {
       this.success = success;
       return this;
     }
@@ -84577,13 +85346,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Set<String>)value);
+          setSuccess((java.util.Set<java.lang.String>)value);
         }
         break;
 
@@ -84614,7 +85383,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -84629,13 +85398,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -84648,11 +85417,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listLocalUsers_result)
@@ -84663,6 +85432,8 @@
     public boolean equals(listLocalUsers_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -84705,29 +85476,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -84738,7 +85505,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -84748,7 +85515,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -84758,7 +85525,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -84768,7 +85535,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -84786,16 +85553,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listLocalUsers_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listLocalUsers_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -84846,7 +85613,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -84854,13 +85621,13 @@
       }
     }
 
-    private static class listLocalUsers_resultStandardSchemeFactory implements SchemeFactory {
+    private static class listLocalUsers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listLocalUsers_resultStandardScheme getScheme() {
         return new listLocalUsers_resultStandardScheme();
       }
     }
 
-    private static class listLocalUsers_resultStandardScheme extends StandardScheme<listLocalUsers_result> {
+    private static class listLocalUsers_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<listLocalUsers_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, listLocalUsers_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -84876,8 +85643,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
                 {
                   org.apache.thrift.protocol.TSet _set434 = iprot.readSetBegin();
-                  struct.success = new HashSet<String>(2*_set434.size);
-                  String _elem435;
+                  struct.success = new java.util.HashSet<java.lang.String>(2*_set434.size);
+                  java.lang.String _elem435;
                   for (int _i436 = 0; _i436 < _set434.size; ++_i436)
                   {
                     _elem435 = iprot.readString();
@@ -84936,7 +85703,7 @@
           oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
           {
             oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.success.size()));
-            for (String _iter437 : struct.success)
+            for (java.lang.String _iter437 : struct.success)
             {
               oprot.writeString(_iter437);
             }
@@ -84965,18 +85732,18 @@
 
     }
 
-    private static class listLocalUsers_resultTupleSchemeFactory implements SchemeFactory {
+    private static class listLocalUsers_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listLocalUsers_resultTupleScheme getScheme() {
         return new listLocalUsers_resultTupleScheme();
       }
     }
 
-    private static class listLocalUsers_resultTupleScheme extends TupleScheme<listLocalUsers_result> {
+    private static class listLocalUsers_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<listLocalUsers_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, listLocalUsers_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -84993,7 +85760,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (String _iter438 : struct.success)
+            for (java.lang.String _iter438 : struct.success)
             {
               oprot.writeString(_iter438);
             }
@@ -85012,13 +85779,13 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, listLocalUsers_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           {
             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);
-            String _elem440;
+            struct.success = new java.util.HashSet<java.lang.String>(2*_set439.size);
+            java.lang.String _elem440;
             for (int _i441 = 0; _i441 < _set439.size; ++_i441)
             {
               _elem440 = iprot.readString();
@@ -85045,6 +85812,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class revokeSystemPermission_args implements org.apache.thrift.TBase<revokeSystemPermission_args, revokeSystemPermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<revokeSystemPermission_args>   {
@@ -85054,14 +85824,11 @@
     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 PERM_FIELD_DESC = new org.apache.thrift.protocol.TField("perm", 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 revokeSystemPermission_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new revokeSystemPermission_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new revokeSystemPermission_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new revokeSystemPermission_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
     /**
      * 
      * @see SystemPermission
@@ -85078,10 +85845,10 @@
        */
       PERM((short)3, "perm");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -85108,21 +85875,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -85131,22 +85898,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.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, SystemPermission.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeSystemPermission_args.class, metaDataMap);
     }
 
@@ -85154,8 +85921,8 @@
     }
 
     public revokeSystemPermission_args(
-      ByteBuffer login,
-      String user,
+      java.nio.ByteBuffer login,
+      java.lang.String user,
       SystemPermission perm)
     {
       this();
@@ -85195,16 +85962,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public revokeSystemPermission_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public revokeSystemPermission_args setLogin(ByteBuffer login) {
+    public revokeSystemPermission_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -85224,11 +85991,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public revokeSystemPermission_args setUser(String user) {
+    public revokeSystemPermission_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -85280,13 +86047,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -85294,7 +86065,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -85309,7 +86080,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -85321,13 +86092,13 @@
         return getPerm();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -85338,11 +86109,11 @@
       case PERM:
         return isSetPerm();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof revokeSystemPermission_args)
@@ -85353,6 +86124,8 @@
     public boolean equals(revokeSystemPermission_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -85386,24 +86159,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_perm = true && (isSetPerm());
-      list.add(present_perm);
-      if (present_perm)
-        list.add(perm.getValue());
+      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
+      if (isSetPerm())
+        hashCode = hashCode * 8191 + perm.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -85414,7 +86184,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -85424,7 +86194,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -85434,7 +86204,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -85452,16 +86222,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("revokeSystemPermission_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeSystemPermission_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -85504,7 +86274,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -85512,13 +86282,13 @@
       }
     }
 
-    private static class revokeSystemPermission_argsStandardSchemeFactory implements SchemeFactory {
+    private static class revokeSystemPermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeSystemPermission_argsStandardScheme getScheme() {
         return new revokeSystemPermission_argsStandardScheme();
       }
     }
 
-    private static class revokeSystemPermission_argsStandardScheme extends StandardScheme<revokeSystemPermission_args> {
+    private static class revokeSystemPermission_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<revokeSystemPermission_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, revokeSystemPermission_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -85590,18 +86360,18 @@
 
     }
 
-    private static class revokeSystemPermission_argsTupleSchemeFactory implements SchemeFactory {
+    private static class revokeSystemPermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeSystemPermission_argsTupleScheme getScheme() {
         return new revokeSystemPermission_argsTupleScheme();
       }
     }
 
-    private static class revokeSystemPermission_argsTupleScheme extends TupleScheme<revokeSystemPermission_args> {
+    private static class revokeSystemPermission_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<revokeSystemPermission_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, revokeSystemPermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -85625,8 +86395,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, revokeSystemPermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -85642,6 +86412,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class revokeSystemPermission_result implements org.apache.thrift.TBase<revokeSystemPermission_result, revokeSystemPermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<revokeSystemPermission_result>   {
@@ -85650,11 +86423,8 @@
     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 revokeSystemPermission_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new revokeSystemPermission_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new revokeSystemPermission_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new revokeSystemPermission_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -85664,10 +86434,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -85692,21 +86462,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -85715,20 +86485,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeSystemPermission_result.class, metaDataMap);
     }
 
@@ -85814,7 +86584,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -85835,7 +86605,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -85844,13 +86614,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -85859,11 +86629,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof revokeSystemPermission_result)
@@ -85874,6 +86644,8 @@
     public boolean equals(revokeSystemPermission_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -85898,19 +86670,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -85921,7 +86691,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -85931,7 +86701,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -85949,16 +86719,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("revokeSystemPermission_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeSystemPermission_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -85993,7 +86763,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -86001,13 +86771,13 @@
       }
     }
 
-    private static class revokeSystemPermission_resultStandardSchemeFactory implements SchemeFactory {
+    private static class revokeSystemPermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeSystemPermission_resultStandardScheme getScheme() {
         return new revokeSystemPermission_resultStandardScheme();
       }
     }
 
-    private static class revokeSystemPermission_resultStandardScheme extends StandardScheme<revokeSystemPermission_result> {
+    private static class revokeSystemPermission_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<revokeSystemPermission_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, revokeSystemPermission_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -86068,18 +86838,18 @@
 
     }
 
-    private static class revokeSystemPermission_resultTupleSchemeFactory implements SchemeFactory {
+    private static class revokeSystemPermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeSystemPermission_resultTupleScheme getScheme() {
         return new revokeSystemPermission_resultTupleScheme();
       }
     }
 
-    private static class revokeSystemPermission_resultTupleScheme extends TupleScheme<revokeSystemPermission_result> {
+    private static class revokeSystemPermission_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<revokeSystemPermission_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, revokeSystemPermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -86097,8 +86867,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, revokeSystemPermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -86112,6 +86882,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class revokeTablePermission_args implements org.apache.thrift.TBase<revokeTablePermission_args, revokeTablePermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<revokeTablePermission_args>   {
@@ -86122,15 +86895,12 @@
     private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", 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 revokeTablePermission_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new revokeTablePermission_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new revokeTablePermission_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new revokeTablePermission_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
-    public String table; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
+    public java.lang.String table; // required
     /**
      * 
      * @see TablePermission
@@ -86148,10 +86918,10 @@
        */
       PERM((short)4, "perm");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -86180,21 +86950,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -86203,15 +86973,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -86220,7 +86990,7 @@
           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, TablePermission.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeTablePermission_args.class, metaDataMap);
     }
 
@@ -86228,9 +86998,9 @@
     }
 
     public revokeTablePermission_args(
-      ByteBuffer login,
-      String user,
-      String table,
+      java.nio.ByteBuffer login,
+      java.lang.String user,
+      java.lang.String table,
       TablePermission perm)
     {
       this();
@@ -86275,16 +87045,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public revokeTablePermission_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public revokeTablePermission_args setLogin(ByteBuffer login) {
+    public revokeTablePermission_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -86304,11 +87074,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public revokeTablePermission_args setUser(String user) {
+    public revokeTablePermission_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -86328,11 +87098,11 @@
       }
     }
 
-    public String getTable() {
+    public java.lang.String getTable() {
       return this.table;
     }
 
-    public revokeTablePermission_args setTable(String table) {
+    public revokeTablePermission_args setTable(java.lang.String table) {
       this.table = table;
       return this;
     }
@@ -86384,13 +87154,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -86398,7 +87172,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -86406,7 +87180,7 @@
         if (value == null) {
           unsetTable();
         } else {
-          setTable((String)value);
+          setTable((java.lang.String)value);
         }
         break;
 
@@ -86421,7 +87195,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -86436,13 +87210,13 @@
         return getPerm();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -86455,11 +87229,11 @@
       case PERM:
         return isSetPerm();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof revokeTablePermission_args)
@@ -86470,6 +87244,8 @@
     public boolean equals(revokeTablePermission_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -86512,29 +87288,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_table = true && (isSetTable());
-      list.add(present_table);
-      if (present_table)
-        list.add(table);
+      hashCode = hashCode * 8191 + ((isSetTable()) ? 131071 : 524287);
+      if (isSetTable())
+        hashCode = hashCode * 8191 + table.hashCode();
 
-      boolean present_perm = true && (isSetPerm());
-      list.add(present_perm);
-      if (present_perm)
-        list.add(perm.getValue());
+      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
+      if (isSetPerm())
+        hashCode = hashCode * 8191 + perm.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -86545,7 +87317,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -86555,7 +87327,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -86565,7 +87337,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
+      lastComparison = java.lang.Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -86575,7 +87347,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -86593,16 +87365,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("revokeTablePermission_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeTablePermission_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -86653,7 +87425,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -86661,13 +87433,13 @@
       }
     }
 
-    private static class revokeTablePermission_argsStandardSchemeFactory implements SchemeFactory {
+    private static class revokeTablePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeTablePermission_argsStandardScheme getScheme() {
         return new revokeTablePermission_argsStandardScheme();
       }
     }
 
-    private static class revokeTablePermission_argsStandardScheme extends StandardScheme<revokeTablePermission_args> {
+    private static class revokeTablePermission_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<revokeTablePermission_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, revokeTablePermission_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -86752,18 +87524,18 @@
 
     }
 
-    private static class revokeTablePermission_argsTupleSchemeFactory implements SchemeFactory {
+    private static class revokeTablePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeTablePermission_argsTupleScheme getScheme() {
         return new revokeTablePermission_argsTupleScheme();
       }
     }
 
-    private static class revokeTablePermission_argsTupleScheme extends TupleScheme<revokeTablePermission_args> {
+    private static class revokeTablePermission_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<revokeTablePermission_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, revokeTablePermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -86793,8 +87565,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, revokeTablePermission_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -86814,6 +87586,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class revokeTablePermission_result implements org.apache.thrift.TBase<revokeTablePermission_result, revokeTablePermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<revokeTablePermission_result>   {
@@ -86823,11 +87598,8 @@
     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 revokeTablePermission_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new revokeTablePermission_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new revokeTablePermission_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new revokeTablePermission_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -86839,10 +87611,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -86869,21 +87641,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -86892,22 +87664,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeTablePermission_result.class, metaDataMap);
     }
 
@@ -87023,7 +87795,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -87052,7 +87824,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -87064,13 +87836,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -87081,11 +87853,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof revokeTablePermission_result)
@@ -87096,6 +87868,8 @@
     public boolean equals(revokeTablePermission_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -87129,24 +87903,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -87157,7 +87928,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -87167,7 +87938,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -87177,7 +87948,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -87195,16 +87966,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("revokeTablePermission_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeTablePermission_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -87247,7 +88018,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -87255,13 +88026,13 @@
       }
     }
 
-    private static class revokeTablePermission_resultStandardSchemeFactory implements SchemeFactory {
+    private static class revokeTablePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeTablePermission_resultStandardScheme getScheme() {
         return new revokeTablePermission_resultStandardScheme();
       }
     }
 
-    private static class revokeTablePermission_resultStandardScheme extends StandardScheme<revokeTablePermission_result> {
+    private static class revokeTablePermission_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<revokeTablePermission_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, revokeTablePermission_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -87336,18 +88107,18 @@
 
     }
 
-    private static class revokeTablePermission_resultTupleSchemeFactory implements SchemeFactory {
+    private static class revokeTablePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeTablePermission_resultTupleScheme getScheme() {
         return new revokeTablePermission_resultTupleScheme();
       }
     }
 
-    private static class revokeTablePermission_resultTupleScheme extends TupleScheme<revokeTablePermission_result> {
+    private static class revokeTablePermission_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<revokeTablePermission_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, revokeTablePermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -87371,8 +88142,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, revokeTablePermission_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -87391,6 +88162,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class grantNamespacePermission_args implements org.apache.thrift.TBase<grantNamespacePermission_args, grantNamespacePermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<grantNamespacePermission_args>   {
@@ -87401,15 +88175,12 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new grantNamespacePermission_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new grantNamespacePermission_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
+    public java.lang.String namespaceName; // required
     /**
      * 
      * @see NamespacePermission
@@ -87427,10 +88198,10 @@
        */
       PERM((short)4, "perm");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -87459,21 +88230,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -87482,15 +88253,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -87499,7 +88270,7 @@
           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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantNamespacePermission_args.class, metaDataMap);
     }
 
@@ -87507,9 +88278,9 @@
     }
 
     public grantNamespacePermission_args(
-      ByteBuffer login,
-      String user,
-      String namespaceName,
+      java.nio.ByteBuffer login,
+      java.lang.String user,
+      java.lang.String namespaceName,
       NamespacePermission perm)
     {
       this();
@@ -87554,16 +88325,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public grantNamespacePermission_args setLogin(ByteBuffer login) {
+    public grantNamespacePermission_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -87583,11 +88354,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public grantNamespacePermission_args setUser(String user) {
+    public grantNamespacePermission_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -87607,11 +88378,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public grantNamespacePermission_args setNamespaceName(String namespaceName) {
+    public grantNamespacePermission_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -87663,13 +88434,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -87677,7 +88452,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -87685,7 +88460,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -87700,7 +88475,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -87715,13 +88490,13 @@
         return getPerm();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -87734,11 +88509,11 @@
       case PERM:
         return isSetPerm();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof grantNamespacePermission_args)
@@ -87749,6 +88524,8 @@
     public boolean equals(grantNamespacePermission_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -87791,29 +88568,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_perm = true && (isSetPerm());
-      list.add(present_perm);
-      if (present_perm)
-        list.add(perm.getValue());
+      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
+      if (isSetPerm())
+        hashCode = hashCode * 8191 + perm.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -87824,7 +88597,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -87834,7 +88607,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -87844,7 +88617,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -87854,7 +88627,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -87872,16 +88645,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("grantNamespacePermission_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantNamespacePermission_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -87932,7 +88705,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -87940,13 +88713,13 @@
       }
     }
 
-    private static class grantNamespacePermission_argsStandardSchemeFactory implements SchemeFactory {
+    private static class grantNamespacePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantNamespacePermission_argsStandardScheme getScheme() {
         return new grantNamespacePermission_argsStandardScheme();
       }
     }
 
-    private static class grantNamespacePermission_argsStandardScheme extends StandardScheme<grantNamespacePermission_args> {
+    private static class grantNamespacePermission_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -88031,18 +88804,18 @@
 
     }
 
-    private static class grantNamespacePermission_argsTupleSchemeFactory implements SchemeFactory {
+    private static class grantNamespacePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantNamespacePermission_argsTupleScheme getScheme() {
         return new grantNamespacePermission_argsTupleScheme();
       }
     }
 
-    private static class grantNamespacePermission_argsTupleScheme extends TupleScheme<grantNamespacePermission_args> {
+    private static class grantNamespacePermission_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -88072,8 +88845,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -88093,6 +88866,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class grantNamespacePermission_result implements org.apache.thrift.TBase<grantNamespacePermission_result, grantNamespacePermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<grantNamespacePermission_result>   {
@@ -88101,11 +88877,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new grantNamespacePermission_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new grantNamespacePermission_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -88115,10 +88888,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -88143,21 +88916,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -88166,20 +88939,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(grantNamespacePermission_result.class, metaDataMap);
     }
 
@@ -88265,7 +89038,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -88286,7 +89059,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -88295,13 +89068,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -88310,11 +89083,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof grantNamespacePermission_result)
@@ -88325,6 +89098,8 @@
     public boolean equals(grantNamespacePermission_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -88349,19 +89124,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -88372,7 +89145,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -88382,7 +89155,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -88400,16 +89173,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("grantNamespacePermission_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("grantNamespacePermission_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -88444,7 +89217,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -88452,13 +89225,13 @@
       }
     }
 
-    private static class grantNamespacePermission_resultStandardSchemeFactory implements SchemeFactory {
+    private static class grantNamespacePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantNamespacePermission_resultStandardScheme getScheme() {
         return new grantNamespacePermission_resultStandardScheme();
       }
     }
 
-    private static class grantNamespacePermission_resultStandardScheme extends StandardScheme<grantNamespacePermission_result> {
+    private static class grantNamespacePermission_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -88519,18 +89292,18 @@
 
     }
 
-    private static class grantNamespacePermission_resultTupleSchemeFactory implements SchemeFactory {
+    private static class grantNamespacePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public grantNamespacePermission_resultTupleScheme getScheme() {
         return new grantNamespacePermission_resultTupleScheme();
       }
     }
 
-    private static class grantNamespacePermission_resultTupleScheme extends TupleScheme<grantNamespacePermission_result> {
+    private static class grantNamespacePermission_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -88548,8 +89321,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -88563,6 +89336,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class hasNamespacePermission_args implements org.apache.thrift.TBase<hasNamespacePermission_args, hasNamespacePermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<hasNamespacePermission_args>   {
@@ -88573,15 +89349,12 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasNamespacePermission_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasNamespacePermission_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
+    public java.lang.String namespaceName; // required
     /**
      * 
      * @see NamespacePermission
@@ -88599,10 +89372,10 @@
        */
       PERM((short)4, "perm");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -88631,21 +89404,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -88654,15 +89427,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -88671,7 +89444,7 @@
           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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasNamespacePermission_args.class, metaDataMap);
     }
 
@@ -88679,9 +89452,9 @@
     }
 
     public hasNamespacePermission_args(
-      ByteBuffer login,
-      String user,
-      String namespaceName,
+      java.nio.ByteBuffer login,
+      java.lang.String user,
+      java.lang.String namespaceName,
       NamespacePermission perm)
     {
       this();
@@ -88726,16 +89499,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public hasNamespacePermission_args setLogin(ByteBuffer login) {
+    public hasNamespacePermission_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -88755,11 +89528,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public hasNamespacePermission_args setUser(String user) {
+    public hasNamespacePermission_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -88779,11 +89552,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public hasNamespacePermission_args setNamespaceName(String namespaceName) {
+    public hasNamespacePermission_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -88835,13 +89608,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -88849,7 +89626,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -88857,7 +89634,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -88872,7 +89649,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -88887,13 +89664,13 @@
         return getPerm();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -88906,11 +89683,11 @@
       case PERM:
         return isSetPerm();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof hasNamespacePermission_args)
@@ -88921,6 +89698,8 @@
     public boolean equals(hasNamespacePermission_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -88963,29 +89742,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_perm = true && (isSetPerm());
-      list.add(present_perm);
-      if (present_perm)
-        list.add(perm.getValue());
+      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
+      if (isSetPerm())
+        hashCode = hashCode * 8191 + perm.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -88996,7 +89771,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -89006,7 +89781,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -89016,7 +89791,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -89026,7 +89801,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -89044,16 +89819,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("hasNamespacePermission_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasNamespacePermission_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -89104,7 +89879,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -89112,13 +89887,13 @@
       }
     }
 
-    private static class hasNamespacePermission_argsStandardSchemeFactory implements SchemeFactory {
+    private static class hasNamespacePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasNamespacePermission_argsStandardScheme getScheme() {
         return new hasNamespacePermission_argsStandardScheme();
       }
     }
 
-    private static class hasNamespacePermission_argsStandardScheme extends StandardScheme<hasNamespacePermission_args> {
+    private static class hasNamespacePermission_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -89203,18 +89978,18 @@
 
     }
 
-    private static class hasNamespacePermission_argsTupleSchemeFactory implements SchemeFactory {
+    private static class hasNamespacePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasNamespacePermission_argsTupleScheme getScheme() {
         return new hasNamespacePermission_argsTupleScheme();
       }
     }
 
-    private static class hasNamespacePermission_argsTupleScheme extends TupleScheme<hasNamespacePermission_args> {
+    private static class hasNamespacePermission_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -89244,8 +90019,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -89265,6 +90040,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class hasNamespacePermission_result implements org.apache.thrift.TBase<hasNamespacePermission_result, hasNamespacePermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<hasNamespacePermission_result>   {
@@ -89274,11 +90052,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasNamespacePermission_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasNamespacePermission_resultTupleSchemeFactory();
 
     public boolean success; // required
     public AccumuloException ouch1; // required
@@ -89290,10 +90065,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -89320,21 +90095,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -89343,7 +90118,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -89351,16 +90126,16 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasNamespacePermission_result.class, metaDataMap);
     }
 
@@ -89416,16 +90191,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public AccumuloException getOuch1() {
@@ -89476,13 +90251,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Boolean)value);
+          setSuccess((java.lang.Boolean)value);
         }
         break;
 
@@ -89505,7 +90280,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return isSuccess();
@@ -89517,13 +90292,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -89534,11 +90309,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof hasNamespacePermission_result)
@@ -89549,6 +90324,8 @@
     public boolean equals(hasNamespacePermission_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -89582,24 +90359,19 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -89610,7 +90382,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -89620,7 +90392,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -89630,7 +90402,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -89648,16 +90420,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("hasNamespacePermission_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasNamespacePermission_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -89696,7 +90468,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -89706,13 +90478,13 @@
       }
     }
 
-    private static class hasNamespacePermission_resultStandardSchemeFactory implements SchemeFactory {
+    private static class hasNamespacePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasNamespacePermission_resultStandardScheme getScheme() {
         return new hasNamespacePermission_resultStandardScheme();
       }
     }
 
-    private static class hasNamespacePermission_resultStandardScheme extends StandardScheme<hasNamespacePermission_result> {
+    private static class hasNamespacePermission_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -89786,18 +90558,18 @@
 
     }
 
-    private static class hasNamespacePermission_resultTupleSchemeFactory implements SchemeFactory {
+    private static class hasNamespacePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasNamespacePermission_resultTupleScheme getScheme() {
         return new hasNamespacePermission_resultTupleScheme();
       }
     }
 
-    private static class hasNamespacePermission_resultTupleScheme extends TupleScheme<hasNamespacePermission_result> {
+    private static class hasNamespacePermission_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -89821,8 +90593,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.success = iprot.readBool();
           struct.setSuccessIsSet(true);
@@ -89840,6 +90612,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class revokeNamespacePermission_args implements org.apache.thrift.TBase<revokeNamespacePermission_args, revokeNamespacePermission_args._Fields>, java.io.Serializable, Cloneable, Comparable<revokeNamespacePermission_args>   {
@@ -89850,15 +90625,12 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new revokeNamespacePermission_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new revokeNamespacePermission_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String user; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String user; // required
+    public java.lang.String namespaceName; // required
     /**
      * 
      * @see NamespacePermission
@@ -89876,10 +90648,10 @@
        */
       PERM((short)4, "perm");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -89908,21 +90680,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -89931,15 +90703,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -89948,7 +90720,7 @@
           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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeNamespacePermission_args.class, metaDataMap);
     }
 
@@ -89956,9 +90728,9 @@
     }
 
     public revokeNamespacePermission_args(
-      ByteBuffer login,
-      String user,
-      String namespaceName,
+      java.nio.ByteBuffer login,
+      java.lang.String user,
+      java.lang.String namespaceName,
       NamespacePermission perm)
     {
       this();
@@ -90003,16 +90775,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public revokeNamespacePermission_args setLogin(ByteBuffer login) {
+    public revokeNamespacePermission_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -90032,11 +90804,11 @@
       }
     }
 
-    public String getUser() {
+    public java.lang.String getUser() {
       return this.user;
     }
 
-    public revokeNamespacePermission_args setUser(String user) {
+    public revokeNamespacePermission_args setUser(java.lang.String user) {
       this.user = user;
       return this;
     }
@@ -90056,11 +90828,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public revokeNamespacePermission_args setNamespaceName(String namespaceName) {
+    public revokeNamespacePermission_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -90112,13 +90884,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -90126,7 +90902,7 @@
         if (value == null) {
           unsetUser();
         } else {
-          setUser((String)value);
+          setUser((java.lang.String)value);
         }
         break;
 
@@ -90134,7 +90910,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -90149,7 +90925,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -90164,13 +90940,13 @@
         return getPerm();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -90183,11 +90959,11 @@
       case PERM:
         return isSetPerm();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof revokeNamespacePermission_args)
@@ -90198,6 +90974,8 @@
     public boolean equals(revokeNamespacePermission_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -90240,29 +91018,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_user = true && (isSetUser());
-      list.add(present_user);
-      if (present_user)
-        list.add(user);
+      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+      if (isSetUser())
+        hashCode = hashCode * 8191 + user.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_perm = true && (isSetPerm());
-      list.add(present_perm);
-      if (present_perm)
-        list.add(perm.getValue());
+      hashCode = hashCode * 8191 + ((isSetPerm()) ? 131071 : 524287);
+      if (isSetPerm())
+        hashCode = hashCode * 8191 + perm.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -90273,7 +91047,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -90283,7 +91057,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -90293,7 +91067,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -90303,7 +91077,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
+      lastComparison = java.lang.Boolean.valueOf(isSetPerm()).compareTo(other.isSetPerm());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -90321,16 +91095,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("revokeNamespacePermission_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeNamespacePermission_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -90381,7 +91155,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -90389,13 +91163,13 @@
       }
     }
 
-    private static class revokeNamespacePermission_argsStandardSchemeFactory implements SchemeFactory {
+    private static class revokeNamespacePermission_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeNamespacePermission_argsStandardScheme getScheme() {
         return new revokeNamespacePermission_argsStandardScheme();
       }
     }
 
-    private static class revokeNamespacePermission_argsStandardScheme extends StandardScheme<revokeNamespacePermission_args> {
+    private static class revokeNamespacePermission_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -90480,18 +91254,18 @@
 
     }
 
-    private static class revokeNamespacePermission_argsTupleSchemeFactory implements SchemeFactory {
+    private static class revokeNamespacePermission_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeNamespacePermission_argsTupleScheme getScheme() {
         return new revokeNamespacePermission_argsTupleScheme();
       }
     }
 
-    private static class revokeNamespacePermission_argsTupleScheme extends TupleScheme<revokeNamespacePermission_args> {
+    private static class revokeNamespacePermission_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -90521,8 +91295,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -90542,6 +91316,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class revokeNamespacePermission_result implements org.apache.thrift.TBase<revokeNamespacePermission_result, revokeNamespacePermission_result._Fields>, java.io.Serializable, Cloneable, Comparable<revokeNamespacePermission_result>   {
@@ -90550,11 +91327,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new revokeNamespacePermission_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new revokeNamespacePermission_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -90564,10 +91338,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -90592,21 +91366,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -90615,20 +91389,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeNamespacePermission_result.class, metaDataMap);
     }
 
@@ -90714,7 +91488,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -90735,7 +91509,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -90744,13 +91518,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -90759,11 +91533,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof revokeNamespacePermission_result)
@@ -90774,6 +91548,8 @@
     public boolean equals(revokeNamespacePermission_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -90798,19 +91574,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -90821,7 +91595,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -90831,7 +91605,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -90849,16 +91623,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("revokeNamespacePermission_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeNamespacePermission_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -90893,7 +91667,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -90901,13 +91675,13 @@
       }
     }
 
-    private static class revokeNamespacePermission_resultStandardSchemeFactory implements SchemeFactory {
+    private static class revokeNamespacePermission_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeNamespacePermission_resultStandardScheme getScheme() {
         return new revokeNamespacePermission_resultStandardScheme();
       }
     }
 
-    private static class revokeNamespacePermission_resultStandardScheme extends StandardScheme<revokeNamespacePermission_result> {
+    private static class revokeNamespacePermission_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -90968,18 +91742,18 @@
 
     }
 
-    private static class revokeNamespacePermission_resultTupleSchemeFactory implements SchemeFactory {
+    private static class revokeNamespacePermission_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public revokeNamespacePermission_resultTupleScheme getScheme() {
         return new revokeNamespacePermission_resultTupleScheme();
       }
     }
 
-    private static class revokeNamespacePermission_resultTupleScheme extends TupleScheme<revokeNamespacePermission_result> {
+    private static class revokeNamespacePermission_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -90997,8 +91771,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -91012,6 +91786,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createBatchScanner_args implements org.apache.thrift.TBase<createBatchScanner_args, createBatchScanner_args._Fields>, java.io.Serializable, Cloneable, Comparable<createBatchScanner_args>   {
@@ -91021,14 +91798,11 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField OPTIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("options", 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 createBatchScanner_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createBatchScanner_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createBatchScanner_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createBatchScanner_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public BatchScanOptions options; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -91037,10 +91811,10 @@
       TABLE_NAME((short)2, "tableName"),
       OPTIONS((short)3, "options");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -91067,21 +91841,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -91090,22 +91864,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.OPTIONS, new org.apache.thrift.meta_data.FieldMetaData("options", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, BatchScanOptions.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createBatchScanner_args.class, metaDataMap);
     }
 
@@ -91113,8 +91887,8 @@
     }
 
     public createBatchScanner_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       BatchScanOptions options)
     {
       this();
@@ -91154,16 +91928,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createBatchScanner_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public createBatchScanner_args setLogin(ByteBuffer login) {
+    public createBatchScanner_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -91183,11 +91957,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public createBatchScanner_args setTableName(String tableName) {
+    public createBatchScanner_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -91231,13 +92005,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -91245,7 +92023,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -91260,7 +92038,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -91272,13 +92050,13 @@
         return getOptions();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -91289,11 +92067,11 @@
       case OPTIONS:
         return isSetOptions();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createBatchScanner_args)
@@ -91304,6 +92082,8 @@
     public boolean equals(createBatchScanner_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -91337,24 +92117,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_options = true && (isSetOptions());
-      list.add(present_options);
-      if (present_options)
-        list.add(options);
+      hashCode = hashCode * 8191 + ((isSetOptions()) ? 131071 : 524287);
+      if (isSetOptions())
+        hashCode = hashCode * 8191 + options.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -91365,7 +92142,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -91375,7 +92152,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -91385,7 +92162,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
+      lastComparison = java.lang.Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -91403,16 +92180,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createBatchScanner_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createBatchScanner_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -91458,7 +92235,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -91466,13 +92243,13 @@
       }
     }
 
-    private static class createBatchScanner_argsStandardSchemeFactory implements SchemeFactory {
+    private static class createBatchScanner_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createBatchScanner_argsStandardScheme getScheme() {
         return new createBatchScanner_argsStandardScheme();
       }
     }
 
-    private static class createBatchScanner_argsStandardScheme extends StandardScheme<createBatchScanner_args> {
+    private static class createBatchScanner_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createBatchScanner_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createBatchScanner_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -91545,18 +92322,18 @@
 
     }
 
-    private static class createBatchScanner_argsTupleSchemeFactory implements SchemeFactory {
+    private static class createBatchScanner_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createBatchScanner_argsTupleScheme getScheme() {
         return new createBatchScanner_argsTupleScheme();
       }
     }
 
-    private static class createBatchScanner_argsTupleScheme extends TupleScheme<createBatchScanner_args> {
+    private static class createBatchScanner_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createBatchScanner_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createBatchScanner_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -91580,8 +92357,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createBatchScanner_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -91598,6 +92375,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createBatchScanner_result implements org.apache.thrift.TBase<createBatchScanner_result, createBatchScanner_result._Fields>, java.io.Serializable, Cloneable, Comparable<createBatchScanner_result>   {
@@ -91608,13 +92388,10 @@
     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 createBatchScanner_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createBatchScanner_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createBatchScanner_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createBatchScanner_resultTupleSchemeFactory();
 
-    public String success; // required
+    public java.lang.String success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -91626,10 +92403,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -91658,21 +92435,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -91681,24 +92458,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createBatchScanner_result.class, metaDataMap);
     }
 
@@ -91706,7 +92483,7 @@
     }
 
     public createBatchScanner_result(
-      String success,
+      java.lang.String success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -91748,11 +92525,11 @@
       this.ouch3 = null;
     }
 
-    public String getSuccess() {
+    public java.lang.String getSuccess() {
       return this.success;
     }
 
-    public createBatchScanner_result setSuccess(String success) {
+    public createBatchScanner_result setSuccess(java.lang.String success) {
       this.success = success;
       return this;
     }
@@ -91844,13 +92621,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((String)value);
+          setSuccess((java.lang.String)value);
         }
         break;
 
@@ -91881,7 +92658,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -91896,13 +92673,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -91915,11 +92692,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createBatchScanner_result)
@@ -91930,6 +92707,8 @@
     public boolean equals(createBatchScanner_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -91972,29 +92751,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -92005,7 +92780,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -92015,7 +92790,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -92025,7 +92800,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -92035,7 +92810,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -92053,16 +92828,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createBatchScanner_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createBatchScanner_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -92113,7 +92888,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -92121,13 +92896,13 @@
       }
     }
 
-    private static class createBatchScanner_resultStandardSchemeFactory implements SchemeFactory {
+    private static class createBatchScanner_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createBatchScanner_resultStandardScheme getScheme() {
         return new createBatchScanner_resultStandardScheme();
       }
     }
 
-    private static class createBatchScanner_resultStandardScheme extends StandardScheme<createBatchScanner_result> {
+    private static class createBatchScanner_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createBatchScanner_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createBatchScanner_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -92215,18 +92990,18 @@
 
     }
 
-    private static class createBatchScanner_resultTupleSchemeFactory implements SchemeFactory {
+    private static class createBatchScanner_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createBatchScanner_resultTupleScheme getScheme() {
         return new createBatchScanner_resultTupleScheme();
       }
     }
 
-    private static class createBatchScanner_resultTupleScheme extends TupleScheme<createBatchScanner_result> {
+    private static class createBatchScanner_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createBatchScanner_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createBatchScanner_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -92256,8 +93031,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createBatchScanner_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = iprot.readString();
           struct.setSuccessIsSet(true);
@@ -92280,6 +93055,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createScanner_args implements org.apache.thrift.TBase<createScanner_args, createScanner_args._Fields>, java.io.Serializable, Cloneable, Comparable<createScanner_args>   {
@@ -92289,14 +93067,11 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField OPTIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("options", 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 createScanner_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createScanner_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createScanner_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createScanner_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public ScanOptions options; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -92305,10 +93080,10 @@
       TABLE_NAME((short)2, "tableName"),
       OPTIONS((short)3, "options");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -92335,21 +93110,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -92358,22 +93133,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.OPTIONS, new org.apache.thrift.meta_data.FieldMetaData("options", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ScanOptions.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createScanner_args.class, metaDataMap);
     }
 
@@ -92381,8 +93156,8 @@
     }
 
     public createScanner_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       ScanOptions options)
     {
       this();
@@ -92422,16 +93197,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createScanner_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public createScanner_args setLogin(ByteBuffer login) {
+    public createScanner_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -92451,11 +93226,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public createScanner_args setTableName(String tableName) {
+    public createScanner_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -92499,13 +93274,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -92513,7 +93292,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -92528,7 +93307,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -92540,13 +93319,13 @@
         return getOptions();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -92557,11 +93336,11 @@
       case OPTIONS:
         return isSetOptions();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createScanner_args)
@@ -92572,6 +93351,8 @@
     public boolean equals(createScanner_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -92605,24 +93386,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_options = true && (isSetOptions());
-      list.add(present_options);
-      if (present_options)
-        list.add(options);
+      hashCode = hashCode * 8191 + ((isSetOptions()) ? 131071 : 524287);
+      if (isSetOptions())
+        hashCode = hashCode * 8191 + options.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -92633,7 +93411,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -92643,7 +93421,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -92653,7 +93431,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
+      lastComparison = java.lang.Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -92671,16 +93449,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createScanner_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createScanner_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -92726,7 +93504,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -92734,13 +93512,13 @@
       }
     }
 
-    private static class createScanner_argsStandardSchemeFactory implements SchemeFactory {
+    private static class createScanner_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createScanner_argsStandardScheme getScheme() {
         return new createScanner_argsStandardScheme();
       }
     }
 
-    private static class createScanner_argsStandardScheme extends StandardScheme<createScanner_args> {
+    private static class createScanner_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createScanner_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createScanner_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -92813,18 +93591,18 @@
 
     }
 
-    private static class createScanner_argsTupleSchemeFactory implements SchemeFactory {
+    private static class createScanner_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createScanner_argsTupleScheme getScheme() {
         return new createScanner_argsTupleScheme();
       }
     }
 
-    private static class createScanner_argsTupleScheme extends TupleScheme<createScanner_args> {
+    private static class createScanner_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createScanner_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createScanner_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -92848,8 +93626,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createScanner_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -92866,6 +93644,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createScanner_result implements org.apache.thrift.TBase<createScanner_result, createScanner_result._Fields>, java.io.Serializable, Cloneable, Comparable<createScanner_result>   {
@@ -92876,13 +93657,10 @@
     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 createScanner_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createScanner_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createScanner_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createScanner_resultTupleSchemeFactory();
 
-    public String success; // required
+    public java.lang.String success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -92894,10 +93672,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -92926,21 +93704,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -92949,24 +93727,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createScanner_result.class, metaDataMap);
     }
 
@@ -92974,7 +93752,7 @@
     }
 
     public createScanner_result(
-      String success,
+      java.lang.String success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -93016,11 +93794,11 @@
       this.ouch3 = null;
     }
 
-    public String getSuccess() {
+    public java.lang.String getSuccess() {
       return this.success;
     }
 
-    public createScanner_result setSuccess(String success) {
+    public createScanner_result setSuccess(java.lang.String success) {
       this.success = success;
       return this;
     }
@@ -93112,13 +93890,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((String)value);
+          setSuccess((java.lang.String)value);
         }
         break;
 
@@ -93149,7 +93927,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -93164,13 +93942,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -93183,11 +93961,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createScanner_result)
@@ -93198,6 +93976,8 @@
     public boolean equals(createScanner_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -93240,29 +94020,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -93273,7 +94049,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -93283,7 +94059,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -93293,7 +94069,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -93303,7 +94079,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -93321,16 +94097,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createScanner_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createScanner_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -93381,7 +94157,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -93389,13 +94165,13 @@
       }
     }
 
-    private static class createScanner_resultStandardSchemeFactory implements SchemeFactory {
+    private static class createScanner_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createScanner_resultStandardScheme getScheme() {
         return new createScanner_resultStandardScheme();
       }
     }
 
-    private static class createScanner_resultStandardScheme extends StandardScheme<createScanner_result> {
+    private static class createScanner_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createScanner_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createScanner_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -93483,18 +94259,18 @@
 
     }
 
-    private static class createScanner_resultTupleSchemeFactory implements SchemeFactory {
+    private static class createScanner_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createScanner_resultTupleScheme getScheme() {
         return new createScanner_resultTupleScheme();
       }
     }
 
-    private static class createScanner_resultTupleScheme extends TupleScheme<createScanner_result> {
+    private static class createScanner_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createScanner_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createScanner_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -93524,8 +94300,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createScanner_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = iprot.readString();
           struct.setSuccessIsSet(true);
@@ -93548,6 +94324,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class hasNext_args implements org.apache.thrift.TBase<hasNext_args, hasNext_args._Fields>, java.io.Serializable, Cloneable, Comparable<hasNext_args>   {
@@ -93555,22 +94334,19 @@
 
     private static final org.apache.thrift.protocol.TField SCANNER_FIELD_DESC = new org.apache.thrift.protocol.TField("scanner", 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 hasNext_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new hasNext_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasNext_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasNext_argsTupleSchemeFactory();
 
-    public String scanner; // required
+    public java.lang.String scanner; // 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 {
       SCANNER((short)1, "scanner");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -93593,21 +94369,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -93616,18 +94392,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.SCANNER, new org.apache.thrift.meta_data.FieldMetaData("scanner", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasNext_args.class, metaDataMap);
     }
 
@@ -93635,7 +94411,7 @@
     }
 
     public hasNext_args(
-      String scanner)
+      java.lang.String scanner)
     {
       this();
       this.scanner = scanner;
@@ -93659,11 +94435,11 @@
       this.scanner = null;
     }
 
-    public String getScanner() {
+    public java.lang.String getScanner() {
       return this.scanner;
     }
 
-    public hasNext_args setScanner(String scanner) {
+    public hasNext_args setScanner(java.lang.String scanner) {
       this.scanner = scanner;
       return this;
     }
@@ -93683,43 +94459,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SCANNER:
         if (value == null) {
           unsetScanner();
         } else {
-          setScanner((String)value);
+          setScanner((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SCANNER:
         return getScanner();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SCANNER:
         return isSetScanner();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof hasNext_args)
@@ -93730,6 +94506,8 @@
     public boolean equals(hasNext_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_scanner = true && this.isSetScanner();
       boolean that_present_scanner = true && that.isSetScanner();
@@ -93745,14 +94523,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_scanner = true && (isSetScanner());
-      list.add(present_scanner);
-      if (present_scanner)
-        list.add(scanner);
+      hashCode = hashCode * 8191 + ((isSetScanner()) ? 131071 : 524287);
+      if (isSetScanner())
+        hashCode = hashCode * 8191 + scanner.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -93763,7 +94540,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
+      lastComparison = java.lang.Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -93781,16 +94558,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("hasNext_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasNext_args(");
       boolean first = true;
 
       sb.append("scanner:");
@@ -93817,7 +94594,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -93825,13 +94602,13 @@
       }
     }
 
-    private static class hasNext_argsStandardSchemeFactory implements SchemeFactory {
+    private static class hasNext_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasNext_argsStandardScheme getScheme() {
         return new hasNext_argsStandardScheme();
       }
     }
 
-    private static class hasNext_argsStandardScheme extends StandardScheme<hasNext_args> {
+    private static class hasNext_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<hasNext_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, hasNext_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -93877,18 +94654,18 @@
 
     }
 
-    private static class hasNext_argsTupleSchemeFactory implements SchemeFactory {
+    private static class hasNext_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasNext_argsTupleScheme getScheme() {
         return new hasNext_argsTupleScheme();
       }
     }
 
-    private static class hasNext_argsTupleScheme extends TupleScheme<hasNext_args> {
+    private static class hasNext_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<hasNext_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, hasNext_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetScanner()) {
           optionals.set(0);
         }
@@ -93900,8 +94677,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, hasNext_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.scanner = iprot.readString();
           struct.setScannerIsSet(true);
@@ -93909,6 +94686,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class hasNext_result implements org.apache.thrift.TBase<hasNext_result, hasNext_result._Fields>, java.io.Serializable, Cloneable, Comparable<hasNext_result>   {
@@ -93917,11 +94697,8 @@
     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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new hasNext_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new hasNext_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasNext_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasNext_resultTupleSchemeFactory();
 
     public boolean success; // required
     public UnknownScanner ouch1; // required
@@ -93931,10 +94708,10 @@
       SUCCESS((short)0, "success"),
       OUCH1((short)1, "ouch1");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -93959,21 +94736,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -93982,7 +94759,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -93990,14 +94767,14 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, UnknownScanner.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasNext_result.class, metaDataMap);
     }
 
@@ -94047,16 +94824,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public UnknownScanner getOuch1() {
@@ -94083,13 +94860,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Boolean)value);
+          setSuccess((java.lang.Boolean)value);
         }
         break;
 
@@ -94104,7 +94881,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return isSuccess();
@@ -94113,13 +94890,13 @@
         return getOuch1();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -94128,11 +94905,11 @@
       case OUCH1:
         return isSetOuch1();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof hasNext_result)
@@ -94143,6 +94920,8 @@
     public boolean equals(hasNext_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -94167,19 +94946,15 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -94190,7 +94965,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -94200,7 +94975,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -94218,16 +94993,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("hasNext_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasNext_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -94258,7 +95033,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -94268,13 +95043,13 @@
       }
     }
 
-    private static class hasNext_resultStandardSchemeFactory implements SchemeFactory {
+    private static class hasNext_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasNext_resultStandardScheme getScheme() {
         return new hasNext_resultStandardScheme();
       }
     }
 
-    private static class hasNext_resultStandardScheme extends StandardScheme<hasNext_result> {
+    private static class hasNext_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<hasNext_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, hasNext_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -94334,18 +95109,18 @@
 
     }
 
-    private static class hasNext_resultTupleSchemeFactory implements SchemeFactory {
+    private static class hasNext_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public hasNext_resultTupleScheme getScheme() {
         return new hasNext_resultTupleScheme();
       }
     }
 
-    private static class hasNext_resultTupleScheme extends TupleScheme<hasNext_result> {
+    private static class hasNext_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<hasNext_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, hasNext_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -94363,8 +95138,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, hasNext_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.success = iprot.readBool();
           struct.setSuccessIsSet(true);
@@ -94377,6 +95152,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class nextEntry_args implements org.apache.thrift.TBase<nextEntry_args, nextEntry_args._Fields>, java.io.Serializable, Cloneable, Comparable<nextEntry_args>   {
@@ -94384,22 +95162,19 @@
 
     private static final org.apache.thrift.protocol.TField SCANNER_FIELD_DESC = new org.apache.thrift.protocol.TField("scanner", 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 nextEntry_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new nextEntry_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new nextEntry_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new nextEntry_argsTupleSchemeFactory();
 
-    public String scanner; // required
+    public java.lang.String scanner; // 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 {
       SCANNER((short)1, "scanner");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -94422,21 +95197,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -94445,18 +95220,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.SCANNER, new org.apache.thrift.meta_data.FieldMetaData("scanner", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(nextEntry_args.class, metaDataMap);
     }
 
@@ -94464,7 +95239,7 @@
     }
 
     public nextEntry_args(
-      String scanner)
+      java.lang.String scanner)
     {
       this();
       this.scanner = scanner;
@@ -94488,11 +95263,11 @@
       this.scanner = null;
     }
 
-    public String getScanner() {
+    public java.lang.String getScanner() {
       return this.scanner;
     }
 
-    public nextEntry_args setScanner(String scanner) {
+    public nextEntry_args setScanner(java.lang.String scanner) {
       this.scanner = scanner;
       return this;
     }
@@ -94512,43 +95287,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SCANNER:
         if (value == null) {
           unsetScanner();
         } else {
-          setScanner((String)value);
+          setScanner((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SCANNER:
         return getScanner();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SCANNER:
         return isSetScanner();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof nextEntry_args)
@@ -94559,6 +95334,8 @@
     public boolean equals(nextEntry_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_scanner = true && this.isSetScanner();
       boolean that_present_scanner = true && that.isSetScanner();
@@ -94574,14 +95351,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_scanner = true && (isSetScanner());
-      list.add(present_scanner);
-      if (present_scanner)
-        list.add(scanner);
+      hashCode = hashCode * 8191 + ((isSetScanner()) ? 131071 : 524287);
+      if (isSetScanner())
+        hashCode = hashCode * 8191 + scanner.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -94592,7 +95368,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
+      lastComparison = java.lang.Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -94610,16 +95386,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("nextEntry_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("nextEntry_args(");
       boolean first = true;
 
       sb.append("scanner:");
@@ -94646,7 +95422,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -94654,13 +95430,13 @@
       }
     }
 
-    private static class nextEntry_argsStandardSchemeFactory implements SchemeFactory {
+    private static class nextEntry_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public nextEntry_argsStandardScheme getScheme() {
         return new nextEntry_argsStandardScheme();
       }
     }
 
-    private static class nextEntry_argsStandardScheme extends StandardScheme<nextEntry_args> {
+    private static class nextEntry_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<nextEntry_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, nextEntry_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -94706,18 +95482,18 @@
 
     }
 
-    private static class nextEntry_argsTupleSchemeFactory implements SchemeFactory {
+    private static class nextEntry_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public nextEntry_argsTupleScheme getScheme() {
         return new nextEntry_argsTupleScheme();
       }
     }
 
-    private static class nextEntry_argsTupleScheme extends TupleScheme<nextEntry_args> {
+    private static class nextEntry_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<nextEntry_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, nextEntry_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetScanner()) {
           optionals.set(0);
         }
@@ -94729,8 +95505,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, nextEntry_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.scanner = iprot.readString();
           struct.setScannerIsSet(true);
@@ -94738,6 +95514,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class nextEntry_result implements org.apache.thrift.TBase<nextEntry_result, nextEntry_result._Fields>, java.io.Serializable, Cloneable, Comparable<nextEntry_result>   {
@@ -94748,11 +95527,8 @@
     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 nextEntry_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new nextEntry_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new nextEntry_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new nextEntry_resultTupleSchemeFactory();
 
     public KeyValueAndPeek success; // required
     public NoMoreEntriesException ouch1; // required
@@ -94766,10 +95542,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -94798,21 +95574,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -94821,24 +95597,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, KeyValueAndPeek.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NoMoreEntriesException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, UnknownScanner.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(nextEntry_result.class, metaDataMap);
     }
 
@@ -94984,7 +95760,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
@@ -95021,7 +95797,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -95036,13 +95812,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -95055,11 +95831,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof nextEntry_result)
@@ -95070,6 +95846,8 @@
     public boolean equals(nextEntry_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -95112,29 +95890,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -95145,7 +95919,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -95155,7 +95929,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -95165,7 +95939,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -95175,7 +95949,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -95193,16 +95967,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("nextEntry_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("nextEntry_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -95256,7 +96030,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -95264,13 +96038,13 @@
       }
     }
 
-    private static class nextEntry_resultStandardSchemeFactory implements SchemeFactory {
+    private static class nextEntry_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public nextEntry_resultStandardScheme getScheme() {
         return new nextEntry_resultStandardScheme();
       }
     }
 
-    private static class nextEntry_resultStandardScheme extends StandardScheme<nextEntry_result> {
+    private static class nextEntry_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<nextEntry_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, nextEntry_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -95359,18 +96133,18 @@
 
     }
 
-    private static class nextEntry_resultTupleSchemeFactory implements SchemeFactory {
+    private static class nextEntry_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public nextEntry_resultTupleScheme getScheme() {
         return new nextEntry_resultTupleScheme();
       }
     }
 
-    private static class nextEntry_resultTupleScheme extends TupleScheme<nextEntry_result> {
+    private static class nextEntry_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<nextEntry_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, nextEntry_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -95400,8 +96174,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, nextEntry_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = new KeyValueAndPeek();
           struct.success.read(iprot);
@@ -95425,6 +96199,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class nextK_args implements org.apache.thrift.TBase<nextK_args, nextK_args._Fields>, java.io.Serializable, Cloneable, Comparable<nextK_args>   {
@@ -95433,13 +96210,10 @@
     private static final org.apache.thrift.protocol.TField SCANNER_FIELD_DESC = new org.apache.thrift.protocol.TField("scanner", org.apache.thrift.protocol.TType.STRING, (short)1);
     private static final org.apache.thrift.protocol.TField K_FIELD_DESC = new org.apache.thrift.protocol.TField("k", org.apache.thrift.protocol.TType.I32, (short)2);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new nextK_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new nextK_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new nextK_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new nextK_argsTupleSchemeFactory();
 
-    public String scanner; // required
+    public java.lang.String scanner; // required
     public int k; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -95447,10 +96221,10 @@
       SCANNER((short)1, "scanner"),
       K((short)2, "k");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -95475,21 +96249,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -95498,7 +96272,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -95506,14 +96280,14 @@
     // isset id assignments
     private static final int __K_ISSET_ID = 0;
     private byte __isset_bitfield = 0;
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.SCANNER, new org.apache.thrift.meta_data.FieldMetaData("scanner", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.K, new org.apache.thrift.meta_data.FieldMetaData("k", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(nextK_args.class, metaDataMap);
     }
 
@@ -95521,7 +96295,7 @@
     }
 
     public nextK_args(
-      String scanner,
+      java.lang.String scanner,
       int k)
     {
       this();
@@ -95552,11 +96326,11 @@
       this.k = 0;
     }
 
-    public String getScanner() {
+    public java.lang.String getScanner() {
       return this.scanner;
     }
 
-    public nextK_args setScanner(String scanner) {
+    public nextK_args setScanner(java.lang.String scanner) {
       this.scanner = scanner;
       return this;
     }
@@ -95587,25 +96361,25 @@
     }
 
     public void unsetK() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __K_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __K_ISSET_ID);
     }
 
     /** Returns true if field k is set (has been assigned a value) and false otherwise */
     public boolean isSetK() {
-      return EncodingUtils.testBit(__isset_bitfield, __K_ISSET_ID);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __K_ISSET_ID);
     }
 
     public void setKIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __K_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __K_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SCANNER:
         if (value == null) {
           unsetScanner();
         } else {
-          setScanner((String)value);
+          setScanner((java.lang.String)value);
         }
         break;
 
@@ -95613,14 +96387,14 @@
         if (value == null) {
           unsetK();
         } else {
-          setK((Integer)value);
+          setK((java.lang.Integer)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SCANNER:
         return getScanner();
@@ -95629,13 +96403,13 @@
         return getK();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -95644,11 +96418,11 @@
       case K:
         return isSetK();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof nextK_args)
@@ -95659,6 +96433,8 @@
     public boolean equals(nextK_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_scanner = true && this.isSetScanner();
       boolean that_present_scanner = true && that.isSetScanner();
@@ -95683,19 +96459,15 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_scanner = true && (isSetScanner());
-      list.add(present_scanner);
-      if (present_scanner)
-        list.add(scanner);
+      hashCode = hashCode * 8191 + ((isSetScanner()) ? 131071 : 524287);
+      if (isSetScanner())
+        hashCode = hashCode * 8191 + scanner.hashCode();
 
-      boolean present_k = true;
-      list.add(present_k);
-      if (present_k)
-        list.add(k);
+      hashCode = hashCode * 8191 + k;
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -95706,7 +96478,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
+      lastComparison = java.lang.Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -95716,7 +96488,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetK()).compareTo(other.isSetK());
+      lastComparison = java.lang.Boolean.valueOf(isSetK()).compareTo(other.isSetK());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -95734,16 +96506,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("nextK_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("nextK_args(");
       boolean first = true;
 
       sb.append("scanner:");
@@ -95774,7 +96546,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -95784,13 +96556,13 @@
       }
     }
 
-    private static class nextK_argsStandardSchemeFactory implements SchemeFactory {
+    private static class nextK_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public nextK_argsStandardScheme getScheme() {
         return new nextK_argsStandardScheme();
       }
     }
 
-    private static class nextK_argsStandardScheme extends StandardScheme<nextK_args> {
+    private static class nextK_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<nextK_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, nextK_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -95847,18 +96619,18 @@
 
     }
 
-    private static class nextK_argsTupleSchemeFactory implements SchemeFactory {
+    private static class nextK_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public nextK_argsTupleScheme getScheme() {
         return new nextK_argsTupleScheme();
       }
     }
 
-    private static class nextK_argsTupleScheme extends TupleScheme<nextK_args> {
+    private static class nextK_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<nextK_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, nextK_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetScanner()) {
           optionals.set(0);
         }
@@ -95876,8 +96648,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, nextK_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.scanner = iprot.readString();
           struct.setScannerIsSet(true);
@@ -95889,6 +96661,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class nextK_result implements org.apache.thrift.TBase<nextK_result, nextK_result._Fields>, java.io.Serializable, Cloneable, Comparable<nextK_result>   {
@@ -95899,11 +96674,8 @@
     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 nextK_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new nextK_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new nextK_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new nextK_resultTupleSchemeFactory();
 
     public ScanResult success; // required
     public NoMoreEntriesException ouch1; // required
@@ -95917,10 +96689,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -95949,21 +96721,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -95972,24 +96744,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, ScanResult.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NoMoreEntriesException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, UnknownScanner.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(nextK_result.class, metaDataMap);
     }
 
@@ -96135,7 +96907,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
@@ -96172,7 +96944,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -96187,13 +96959,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -96206,11 +96978,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof nextK_result)
@@ -96221,6 +96993,8 @@
     public boolean equals(nextK_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -96263,29 +97037,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -96296,7 +97066,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -96306,7 +97076,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -96316,7 +97086,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -96326,7 +97096,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -96344,16 +97114,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("nextK_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("nextK_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -96407,7 +97177,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -96415,13 +97185,13 @@
       }
     }
 
-    private static class nextK_resultStandardSchemeFactory implements SchemeFactory {
+    private static class nextK_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public nextK_resultStandardScheme getScheme() {
         return new nextK_resultStandardScheme();
       }
     }
 
-    private static class nextK_resultStandardScheme extends StandardScheme<nextK_result> {
+    private static class nextK_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<nextK_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, nextK_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -96510,18 +97280,18 @@
 
     }
 
-    private static class nextK_resultTupleSchemeFactory implements SchemeFactory {
+    private static class nextK_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public nextK_resultTupleScheme getScheme() {
         return new nextK_resultTupleScheme();
       }
     }
 
-    private static class nextK_resultTupleScheme extends TupleScheme<nextK_result> {
+    private static class nextK_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<nextK_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, nextK_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -96551,8 +97321,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, nextK_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = new ScanResult();
           struct.success.read(iprot);
@@ -96576,6 +97346,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class closeScanner_args implements org.apache.thrift.TBase<closeScanner_args, closeScanner_args._Fields>, java.io.Serializable, Cloneable, Comparable<closeScanner_args>   {
@@ -96583,22 +97356,19 @@
 
     private static final org.apache.thrift.protocol.TField SCANNER_FIELD_DESC = new org.apache.thrift.protocol.TField("scanner", 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 closeScanner_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new closeScanner_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new closeScanner_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new closeScanner_argsTupleSchemeFactory();
 
-    public String scanner; // required
+    public java.lang.String scanner; // 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 {
       SCANNER((short)1, "scanner");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -96621,21 +97391,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -96644,18 +97414,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.SCANNER, new org.apache.thrift.meta_data.FieldMetaData("scanner", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeScanner_args.class, metaDataMap);
     }
 
@@ -96663,7 +97433,7 @@
     }
 
     public closeScanner_args(
-      String scanner)
+      java.lang.String scanner)
     {
       this();
       this.scanner = scanner;
@@ -96687,11 +97457,11 @@
       this.scanner = null;
     }
 
-    public String getScanner() {
+    public java.lang.String getScanner() {
       return this.scanner;
     }
 
-    public closeScanner_args setScanner(String scanner) {
+    public closeScanner_args setScanner(java.lang.String scanner) {
       this.scanner = scanner;
       return this;
     }
@@ -96711,43 +97481,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SCANNER:
         if (value == null) {
           unsetScanner();
         } else {
-          setScanner((String)value);
+          setScanner((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SCANNER:
         return getScanner();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SCANNER:
         return isSetScanner();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof closeScanner_args)
@@ -96758,6 +97528,8 @@
     public boolean equals(closeScanner_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_scanner = true && this.isSetScanner();
       boolean that_present_scanner = true && that.isSetScanner();
@@ -96773,14 +97545,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_scanner = true && (isSetScanner());
-      list.add(present_scanner);
-      if (present_scanner)
-        list.add(scanner);
+      hashCode = hashCode * 8191 + ((isSetScanner()) ? 131071 : 524287);
+      if (isSetScanner())
+        hashCode = hashCode * 8191 + scanner.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -96791,7 +97562,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
+      lastComparison = java.lang.Boolean.valueOf(isSetScanner()).compareTo(other.isSetScanner());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -96809,16 +97580,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("closeScanner_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeScanner_args(");
       boolean first = true;
 
       sb.append("scanner:");
@@ -96845,7 +97616,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -96853,13 +97624,13 @@
       }
     }
 
-    private static class closeScanner_argsStandardSchemeFactory implements SchemeFactory {
+    private static class closeScanner_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeScanner_argsStandardScheme getScheme() {
         return new closeScanner_argsStandardScheme();
       }
     }
 
-    private static class closeScanner_argsStandardScheme extends StandardScheme<closeScanner_args> {
+    private static class closeScanner_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<closeScanner_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, closeScanner_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -96905,18 +97676,18 @@
 
     }
 
-    private static class closeScanner_argsTupleSchemeFactory implements SchemeFactory {
+    private static class closeScanner_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeScanner_argsTupleScheme getScheme() {
         return new closeScanner_argsTupleScheme();
       }
     }
 
-    private static class closeScanner_argsTupleScheme extends TupleScheme<closeScanner_args> {
+    private static class closeScanner_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<closeScanner_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, closeScanner_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetScanner()) {
           optionals.set(0);
         }
@@ -96928,8 +97699,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, closeScanner_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.scanner = iprot.readString();
           struct.setScannerIsSet(true);
@@ -96937,6 +97708,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class closeScanner_result implements org.apache.thrift.TBase<closeScanner_result, closeScanner_result._Fields>, java.io.Serializable, Cloneable, Comparable<closeScanner_result>   {
@@ -96944,11 +97718,8 @@
 
     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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new closeScanner_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new closeScanner_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new closeScanner_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new closeScanner_resultTupleSchemeFactory();
 
     public UnknownScanner ouch1; // required
 
@@ -96956,10 +97727,10 @@
     public enum _Fields implements org.apache.thrift.TFieldIdEnum {
       OUCH1((short)1, "ouch1");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -96982,21 +97753,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -97005,18 +97776,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, UnknownScanner.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeScanner_result.class, metaDataMap);
     }
 
@@ -97072,7 +97843,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -97085,30 +97856,30 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case OUCH1:
         return isSetOuch1();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof closeScanner_result)
@@ -97119,6 +97890,8 @@
     public boolean equals(closeScanner_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -97134,14 +97907,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -97152,7 +97924,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -97170,16 +97942,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("closeScanner_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeScanner_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -97206,7 +97978,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -97214,13 +97986,13 @@
       }
     }
 
-    private static class closeScanner_resultStandardSchemeFactory implements SchemeFactory {
+    private static class closeScanner_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeScanner_resultStandardScheme getScheme() {
         return new closeScanner_resultStandardScheme();
       }
     }
 
-    private static class closeScanner_resultStandardScheme extends StandardScheme<closeScanner_result> {
+    private static class closeScanner_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<closeScanner_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, closeScanner_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -97267,18 +98039,18 @@
 
     }
 
-    private static class closeScanner_resultTupleSchemeFactory implements SchemeFactory {
+    private static class closeScanner_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeScanner_resultTupleScheme getScheme() {
         return new closeScanner_resultTupleScheme();
       }
     }
 
-    private static class closeScanner_resultTupleScheme extends TupleScheme<closeScanner_result> {
+    private static class closeScanner_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<closeScanner_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, closeScanner_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -97290,8 +98062,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, closeScanner_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.ouch1 = new UnknownScanner();
           struct.ouch1.read(iprot);
@@ -97300,6 +98072,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class updateAndFlush_args implements org.apache.thrift.TBase<updateAndFlush_args, updateAndFlush_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateAndFlush_args>   {
@@ -97309,15 +98084,12 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField CELLS_FIELD_DESC = new org.apache.thrift.protocol.TField("cells", org.apache.thrift.protocol.TType.MAP, (short)3);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new updateAndFlush_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new updateAndFlush_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateAndFlush_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateAndFlush_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public Map<ByteBuffer,List<ColumnUpdate>> cells; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells; // 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 {
@@ -97325,10 +98097,10 @@
       TABLE_NAME((short)2, "tableName"),
       CELLS((short)3, "cells");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -97355,21 +98127,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -97378,15 +98150,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -97396,7 +98168,7 @@
               new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true), 
               new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
                   new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnUpdate.class)))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateAndFlush_args.class, metaDataMap);
     }
 
@@ -97404,9 +98176,9 @@
     }
 
     public updateAndFlush_args(
-      ByteBuffer login,
-      String tableName,
-      Map<ByteBuffer,List<ColumnUpdate>> cells)
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -97425,15 +98197,15 @@
         this.tableName = other.tableName;
       }
       if (other.isSetCells()) {
-        Map<ByteBuffer,List<ColumnUpdate>> __this__cells = new HashMap<ByteBuffer,List<ColumnUpdate>>(other.cells.size());
-        for (Map.Entry<ByteBuffer, List<ColumnUpdate>> other_element : other.cells.entrySet()) {
+        java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> __this__cells = new java.util.HashMap<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>(other.cells.size());
+        for (java.util.Map.Entry<java.nio.ByteBuffer, java.util.List<ColumnUpdate>> other_element : other.cells.entrySet()) {
 
-          ByteBuffer other_element_key = other_element.getKey();
-          List<ColumnUpdate> other_element_value = other_element.getValue();
+          java.nio.ByteBuffer other_element_key = other_element.getKey();
+          java.util.List<ColumnUpdate> other_element_value = other_element.getValue();
 
-          ByteBuffer __this__cells_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
+          java.nio.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());
+          java.util.List<ColumnUpdate> __this__cells_copy_value = new java.util.ArrayList<ColumnUpdate>(other_element_value.size());
           for (ColumnUpdate other_element_value_element : other_element_value) {
             __this__cells_copy_value.add(new ColumnUpdate(other_element_value_element));
           }
@@ -97460,16 +98232,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public updateAndFlush_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public updateAndFlush_args setLogin(ByteBuffer login) {
+    public updateAndFlush_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -97489,11 +98261,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public updateAndFlush_args setTableName(String tableName) {
+    public updateAndFlush_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -97517,18 +98289,18 @@
       return (this.cells == null) ? 0 : this.cells.size();
     }
 
-    public void putToCells(ByteBuffer key, List<ColumnUpdate> val) {
+    public void putToCells(java.nio.ByteBuffer key, java.util.List<ColumnUpdate> val) {
       if (this.cells == null) {
-        this.cells = new HashMap<ByteBuffer,List<ColumnUpdate>>();
+        this.cells = new java.util.HashMap<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>();
       }
       this.cells.put(key, val);
     }
 
-    public Map<ByteBuffer,List<ColumnUpdate>> getCells() {
+    public java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> getCells() {
       return this.cells;
     }
 
-    public updateAndFlush_args setCells(Map<ByteBuffer,List<ColumnUpdate>> cells) {
+    public updateAndFlush_args setCells(java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) {
       this.cells = cells;
       return this;
     }
@@ -97548,13 +98320,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -97562,7 +98338,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -97570,14 +98346,14 @@
         if (value == null) {
           unsetCells();
         } else {
-          setCells((Map<ByteBuffer,List<ColumnUpdate>>)value);
+          setCells((java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -97589,13 +98365,13 @@
         return getCells();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -97606,11 +98382,11 @@
       case CELLS:
         return isSetCells();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof updateAndFlush_args)
@@ -97621,6 +98397,8 @@
     public boolean equals(updateAndFlush_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -97654,24 +98432,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_cells = true && (isSetCells());
-      list.add(present_cells);
-      if (present_cells)
-        list.add(cells);
+      hashCode = hashCode * 8191 + ((isSetCells()) ? 131071 : 524287);
+      if (isSetCells())
+        hashCode = hashCode * 8191 + cells.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -97682,7 +98457,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -97692,7 +98467,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -97702,7 +98477,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetCells()).compareTo(other.isSetCells());
+      lastComparison = java.lang.Boolean.valueOf(isSetCells()).compareTo(other.isSetCells());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -97720,16 +98495,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("updateAndFlush_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateAndFlush_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -97772,7 +98547,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -97780,13 +98555,13 @@
       }
     }
 
-    private static class updateAndFlush_argsStandardSchemeFactory implements SchemeFactory {
+    private static class updateAndFlush_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateAndFlush_argsStandardScheme getScheme() {
         return new updateAndFlush_argsStandardScheme();
       }
     }
 
-    private static class updateAndFlush_argsStandardScheme extends StandardScheme<updateAndFlush_args> {
+    private static class updateAndFlush_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateAndFlush_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, updateAndFlush_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -97818,15 +98593,15 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map442 = iprot.readMapBegin();
-                  struct.cells = new HashMap<ByteBuffer,List<ColumnUpdate>>(2*_map442.size);
-                  ByteBuffer _key443;
-                  List<ColumnUpdate> _val444;
+                  struct.cells = new java.util.HashMap<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>(2*_map442.size);
+                  java.nio.ByteBuffer _key443;
+                  java.util.List<ColumnUpdate> _val444;
                   for (int _i445 = 0; _i445 < _map442.size; ++_i445)
                   {
                     _key443 = iprot.readBinary();
                     {
                       org.apache.thrift.protocol.TList _list446 = iprot.readListBegin();
-                      _val444 = new ArrayList<ColumnUpdate>(_list446.size);
+                      _val444 = new java.util.ArrayList<ColumnUpdate>(_list446.size);
                       ColumnUpdate _elem447;
                       for (int _i448 = 0; _i448 < _list446.size; ++_i448)
                       {
@@ -97874,7 +98649,7 @@
           oprot.writeFieldBegin(CELLS_FIELD_DESC);
           {
             oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, struct.cells.size()));
-            for (Map.Entry<ByteBuffer, List<ColumnUpdate>> _iter449 : struct.cells.entrySet())
+            for (java.util.Map.Entry<java.nio.ByteBuffer, java.util.List<ColumnUpdate>> _iter449 : struct.cells.entrySet())
             {
               oprot.writeBinary(_iter449.getKey());
               {
@@ -97896,18 +98671,18 @@
 
     }
 
-    private static class updateAndFlush_argsTupleSchemeFactory implements SchemeFactory {
+    private static class updateAndFlush_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateAndFlush_argsTupleScheme getScheme() {
         return new updateAndFlush_argsTupleScheme();
       }
     }
 
-    private static class updateAndFlush_argsTupleScheme extends TupleScheme<updateAndFlush_args> {
+    private static class updateAndFlush_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateAndFlush_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, updateAndFlush_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -97927,7 +98702,7 @@
         if (struct.isSetCells()) {
           {
             oprot.writeI32(struct.cells.size());
-            for (Map.Entry<ByteBuffer, List<ColumnUpdate>> _iter451 : struct.cells.entrySet())
+            for (java.util.Map.Entry<java.nio.ByteBuffer, java.util.List<ColumnUpdate>> _iter451 : struct.cells.entrySet())
             {
               oprot.writeBinary(_iter451.getKey());
               {
@@ -97944,8 +98719,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, updateAndFlush_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -97957,15 +98732,15 @@
         if (incoming.get(2)) {
           {
             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);
-            ByteBuffer _key454;
-            List<ColumnUpdate> _val455;
+            struct.cells = new java.util.HashMap<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>(2*_map453.size);
+            java.nio.ByteBuffer _key454;
+            java.util.List<ColumnUpdate> _val455;
             for (int _i456 = 0; _i456 < _map453.size; ++_i456)
             {
               _key454 = iprot.readBinary();
               {
                 org.apache.thrift.protocol.TList _list457 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
-                _val455 = new ArrayList<ColumnUpdate>(_list457.size);
+                _val455 = new java.util.ArrayList<ColumnUpdate>(_list457.size);
                 ColumnUpdate _elem458;
                 for (int _i459 = 0; _i459 < _list457.size; ++_i459)
                 {
@@ -97982,6 +98757,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class updateAndFlush_result implements org.apache.thrift.TBase<updateAndFlush_result, updateAndFlush_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateAndFlush_result>   {
@@ -97992,11 +98770,8 @@
     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 updateAndFlush_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new updateAndFlush_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateAndFlush_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateAndFlush_resultTupleSchemeFactory();
 
     public AccumuloException outch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -98010,10 +98785,10 @@
       OUCH3((short)3, "ouch3"),
       OUCH4((short)4, "ouch4");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -98042,21 +98817,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -98065,24 +98840,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.OUTCH1, new org.apache.thrift.meta_data.FieldMetaData("outch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, MutationsRejectedException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateAndFlush_result.class, metaDataMap);
     }
 
@@ -98228,7 +99003,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUTCH1:
         if (value == null) {
@@ -98265,7 +99040,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUTCH1:
         return getOutch1();
@@ -98280,13 +99055,13 @@
         return getOuch4();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -98299,11 +99074,11 @@
       case OUCH4:
         return isSetOuch4();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof updateAndFlush_result)
@@ -98314,6 +99089,8 @@
     public boolean equals(updateAndFlush_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_outch1 = true && this.isSetOutch1();
       boolean that_present_outch1 = true && that.isSetOutch1();
@@ -98356,29 +99133,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_outch1 = true && (isSetOutch1());
-      list.add(present_outch1);
-      if (present_outch1)
-        list.add(outch1);
+      hashCode = hashCode * 8191 + ((isSetOutch1()) ? 131071 : 524287);
+      if (isSetOutch1())
+        hashCode = hashCode * 8191 + outch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      boolean present_ouch4 = true && (isSetOuch4());
-      list.add(present_ouch4);
-      if (present_ouch4)
-        list.add(ouch4);
+      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
+      if (isSetOuch4())
+        hashCode = hashCode * 8191 + ouch4.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -98389,7 +99162,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOutch1()).compareTo(other.isSetOutch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOutch1()).compareTo(other.isSetOutch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -98399,7 +99172,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -98409,7 +99182,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -98419,7 +99192,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -98437,16 +99210,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("updateAndFlush_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateAndFlush_result(");
       boolean first = true;
 
       sb.append("outch1:");
@@ -98497,7 +99270,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -98505,13 +99278,13 @@
       }
     }
 
-    private static class updateAndFlush_resultStandardSchemeFactory implements SchemeFactory {
+    private static class updateAndFlush_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateAndFlush_resultStandardScheme getScheme() {
         return new updateAndFlush_resultStandardScheme();
       }
     }
 
-    private static class updateAndFlush_resultStandardScheme extends StandardScheme<updateAndFlush_result> {
+    private static class updateAndFlush_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateAndFlush_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, updateAndFlush_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -98600,18 +99373,18 @@
 
     }
 
-    private static class updateAndFlush_resultTupleSchemeFactory implements SchemeFactory {
+    private static class updateAndFlush_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateAndFlush_resultTupleScheme getScheme() {
         return new updateAndFlush_resultTupleScheme();
       }
     }
 
-    private static class updateAndFlush_resultTupleScheme extends TupleScheme<updateAndFlush_result> {
+    private static class updateAndFlush_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateAndFlush_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, updateAndFlush_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOutch1()) {
           optionals.set(0);
         }
@@ -98641,8 +99414,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, updateAndFlush_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.outch1 = new AccumuloException();
           struct.outch1.read(iprot);
@@ -98666,6 +99439,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createWriter_args implements org.apache.thrift.TBase<createWriter_args, createWriter_args._Fields>, java.io.Serializable, Cloneable, Comparable<createWriter_args>   {
@@ -98675,14 +99451,11 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField OPTS_FIELD_DESC = new org.apache.thrift.protocol.TField("opts", 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 createWriter_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createWriter_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createWriter_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createWriter_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public WriterOptions opts; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -98691,10 +99464,10 @@
       TABLE_NAME((short)2, "tableName"),
       OPTS((short)3, "opts");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -98721,21 +99494,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -98744,22 +99517,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.OPTS, new org.apache.thrift.meta_data.FieldMetaData("opts", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, WriterOptions.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createWriter_args.class, metaDataMap);
     }
 
@@ -98767,8 +99540,8 @@
     }
 
     public createWriter_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       WriterOptions opts)
     {
       this();
@@ -98808,16 +99581,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createWriter_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public createWriter_args setLogin(ByteBuffer login) {
+    public createWriter_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -98837,11 +99610,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public createWriter_args setTableName(String tableName) {
+    public createWriter_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -98885,13 +99658,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -98899,7 +99676,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -98914,7 +99691,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -98926,13 +99703,13 @@
         return getOpts();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -98943,11 +99720,11 @@
       case OPTS:
         return isSetOpts();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createWriter_args)
@@ -98958,6 +99735,8 @@
     public boolean equals(createWriter_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -98991,24 +99770,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_opts = true && (isSetOpts());
-      list.add(present_opts);
-      if (present_opts)
-        list.add(opts);
+      hashCode = hashCode * 8191 + ((isSetOpts()) ? 131071 : 524287);
+      if (isSetOpts())
+        hashCode = hashCode * 8191 + opts.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -99019,7 +99795,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -99029,7 +99805,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -99039,7 +99815,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOpts()).compareTo(other.isSetOpts());
+      lastComparison = java.lang.Boolean.valueOf(isSetOpts()).compareTo(other.isSetOpts());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -99057,16 +99833,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createWriter_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createWriter_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -99112,7 +99888,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -99120,13 +99896,13 @@
       }
     }
 
-    private static class createWriter_argsStandardSchemeFactory implements SchemeFactory {
+    private static class createWriter_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createWriter_argsStandardScheme getScheme() {
         return new createWriter_argsStandardScheme();
       }
     }
 
-    private static class createWriter_argsStandardScheme extends StandardScheme<createWriter_args> {
+    private static class createWriter_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createWriter_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createWriter_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -99199,18 +99975,18 @@
 
     }
 
-    private static class createWriter_argsTupleSchemeFactory implements SchemeFactory {
+    private static class createWriter_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createWriter_argsTupleScheme getScheme() {
         return new createWriter_argsTupleScheme();
       }
     }
 
-    private static class createWriter_argsTupleScheme extends TupleScheme<createWriter_args> {
+    private static class createWriter_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createWriter_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createWriter_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -99234,8 +100010,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createWriter_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -99252,6 +100028,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createWriter_result implements org.apache.thrift.TBase<createWriter_result, createWriter_result._Fields>, java.io.Serializable, Cloneable, Comparable<createWriter_result>   {
@@ -99262,13 +100041,10 @@
     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 createWriter_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createWriter_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createWriter_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createWriter_resultTupleSchemeFactory();
 
-    public String success; // required
+    public java.lang.String success; // required
     public AccumuloException outch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -99280,10 +100056,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -99312,21 +100088,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -99335,24 +100111,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
       tmpMap.put(_Fields.OUTCH1, new org.apache.thrift.meta_data.FieldMetaData("outch1", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createWriter_result.class, metaDataMap);
     }
 
@@ -99360,7 +100136,7 @@
     }
 
     public createWriter_result(
-      String success,
+      java.lang.String success,
       AccumuloException outch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -99402,11 +100178,11 @@
       this.ouch3 = null;
     }
 
-    public String getSuccess() {
+    public java.lang.String getSuccess() {
       return this.success;
     }
 
-    public createWriter_result setSuccess(String success) {
+    public createWriter_result setSuccess(java.lang.String success) {
       this.success = success;
       return this;
     }
@@ -99498,13 +100274,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((String)value);
+          setSuccess((java.lang.String)value);
         }
         break;
 
@@ -99535,7 +100311,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -99550,13 +100326,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -99569,11 +100345,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createWriter_result)
@@ -99584,6 +100360,8 @@
     public boolean equals(createWriter_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -99626,29 +100404,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_outch1 = true && (isSetOutch1());
-      list.add(present_outch1);
-      if (present_outch1)
-        list.add(outch1);
+      hashCode = hashCode * 8191 + ((isSetOutch1()) ? 131071 : 524287);
+      if (isSetOutch1())
+        hashCode = hashCode * 8191 + outch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -99659,7 +100433,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -99669,7 +100443,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOutch1()).compareTo(other.isSetOutch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOutch1()).compareTo(other.isSetOutch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -99679,7 +100453,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -99689,7 +100463,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -99707,16 +100481,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createWriter_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createWriter_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -99767,7 +100541,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -99775,13 +100549,13 @@
       }
     }
 
-    private static class createWriter_resultStandardSchemeFactory implements SchemeFactory {
+    private static class createWriter_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createWriter_resultStandardScheme getScheme() {
         return new createWriter_resultStandardScheme();
       }
     }
 
-    private static class createWriter_resultStandardScheme extends StandardScheme<createWriter_result> {
+    private static class createWriter_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createWriter_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createWriter_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -99869,18 +100643,18 @@
 
     }
 
-    private static class createWriter_resultTupleSchemeFactory implements SchemeFactory {
+    private static class createWriter_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createWriter_resultTupleScheme getScheme() {
         return new createWriter_resultTupleScheme();
       }
     }
 
-    private static class createWriter_resultTupleScheme extends TupleScheme<createWriter_result> {
+    private static class createWriter_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createWriter_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createWriter_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -99910,8 +100684,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createWriter_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = iprot.readString();
           struct.setSuccessIsSet(true);
@@ -99934,6 +100708,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class update_args implements org.apache.thrift.TBase<update_args, update_args._Fields>, java.io.Serializable, Cloneable, Comparable<update_args>   {
@@ -99942,24 +100719,21 @@
     private static final org.apache.thrift.protocol.TField WRITER_FIELD_DESC = new org.apache.thrift.protocol.TField("writer", org.apache.thrift.protocol.TType.STRING, (short)1);
     private static final org.apache.thrift.protocol.TField CELLS_FIELD_DESC = new org.apache.thrift.protocol.TField("cells", org.apache.thrift.protocol.TType.MAP, (short)2);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new update_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new update_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new update_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new update_argsTupleSchemeFactory();
 
-    public String writer; // required
-    public Map<ByteBuffer,List<ColumnUpdate>> cells; // required
+    public java.lang.String writer; // required
+    public java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells; // 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 {
       WRITER((short)1, "writer"),
       CELLS((short)2, "cells");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -99984,21 +100758,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -100007,15 +100781,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.WRITER, new org.apache.thrift.meta_data.FieldMetaData("writer", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.CELLS, new org.apache.thrift.meta_data.FieldMetaData("cells", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -100023,7 +100797,7 @@
               new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true), 
               new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
                   new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnUpdate.class)))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(update_args.class, metaDataMap);
     }
 
@@ -100031,8 +100805,8 @@
     }
 
     public update_args(
-      String writer,
-      Map<ByteBuffer,List<ColumnUpdate>> cells)
+      java.lang.String writer,
+      java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells)
     {
       this();
       this.writer = writer;
@@ -100047,15 +100821,15 @@
         this.writer = other.writer;
       }
       if (other.isSetCells()) {
-        Map<ByteBuffer,List<ColumnUpdate>> __this__cells = new HashMap<ByteBuffer,List<ColumnUpdate>>(other.cells.size());
-        for (Map.Entry<ByteBuffer, List<ColumnUpdate>> other_element : other.cells.entrySet()) {
+        java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> __this__cells = new java.util.HashMap<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>(other.cells.size());
+        for (java.util.Map.Entry<java.nio.ByteBuffer, java.util.List<ColumnUpdate>> other_element : other.cells.entrySet()) {
 
-          ByteBuffer other_element_key = other_element.getKey();
-          List<ColumnUpdate> other_element_value = other_element.getValue();
+          java.nio.ByteBuffer other_element_key = other_element.getKey();
+          java.util.List<ColumnUpdate> other_element_value = other_element.getValue();
 
-          ByteBuffer __this__cells_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
+          java.nio.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());
+          java.util.List<ColumnUpdate> __this__cells_copy_value = new java.util.ArrayList<ColumnUpdate>(other_element_value.size());
           for (ColumnUpdate other_element_value_element : other_element_value) {
             __this__cells_copy_value.add(new ColumnUpdate(other_element_value_element));
           }
@@ -100076,11 +100850,11 @@
       this.cells = null;
     }
 
-    public String getWriter() {
+    public java.lang.String getWriter() {
       return this.writer;
     }
 
-    public update_args setWriter(String writer) {
+    public update_args setWriter(java.lang.String writer) {
       this.writer = writer;
       return this;
     }
@@ -100104,18 +100878,18 @@
       return (this.cells == null) ? 0 : this.cells.size();
     }
 
-    public void putToCells(ByteBuffer key, List<ColumnUpdate> val) {
+    public void putToCells(java.nio.ByteBuffer key, java.util.List<ColumnUpdate> val) {
       if (this.cells == null) {
-        this.cells = new HashMap<ByteBuffer,List<ColumnUpdate>>();
+        this.cells = new java.util.HashMap<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>();
       }
       this.cells.put(key, val);
     }
 
-    public Map<ByteBuffer,List<ColumnUpdate>> getCells() {
+    public java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> getCells() {
       return this.cells;
     }
 
-    public update_args setCells(Map<ByteBuffer,List<ColumnUpdate>> cells) {
+    public update_args setCells(java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>> cells) {
       this.cells = cells;
       return this;
     }
@@ -100135,13 +100909,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case WRITER:
         if (value == null) {
           unsetWriter();
         } else {
-          setWriter((String)value);
+          setWriter((java.lang.String)value);
         }
         break;
 
@@ -100149,14 +100923,14 @@
         if (value == null) {
           unsetCells();
         } else {
-          setCells((Map<ByteBuffer,List<ColumnUpdate>>)value);
+          setCells((java.util.Map<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case WRITER:
         return getWriter();
@@ -100165,13 +100939,13 @@
         return getCells();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -100180,11 +100954,11 @@
       case CELLS:
         return isSetCells();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof update_args)
@@ -100195,6 +100969,8 @@
     public boolean equals(update_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_writer = true && this.isSetWriter();
       boolean that_present_writer = true && that.isSetWriter();
@@ -100219,19 +100995,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_writer = true && (isSetWriter());
-      list.add(present_writer);
-      if (present_writer)
-        list.add(writer);
+      hashCode = hashCode * 8191 + ((isSetWriter()) ? 131071 : 524287);
+      if (isSetWriter())
+        hashCode = hashCode * 8191 + writer.hashCode();
 
-      boolean present_cells = true && (isSetCells());
-      list.add(present_cells);
-      if (present_cells)
-        list.add(cells);
+      hashCode = hashCode * 8191 + ((isSetCells()) ? 131071 : 524287);
+      if (isSetCells())
+        hashCode = hashCode * 8191 + cells.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -100242,7 +101016,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetWriter()).compareTo(other.isSetWriter());
+      lastComparison = java.lang.Boolean.valueOf(isSetWriter()).compareTo(other.isSetWriter());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -100252,7 +101026,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetCells()).compareTo(other.isSetCells());
+      lastComparison = java.lang.Boolean.valueOf(isSetCells()).compareTo(other.isSetCells());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -100270,16 +101044,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("update_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("update_args(");
       boolean first = true;
 
       sb.append("writer:");
@@ -100314,7 +101088,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -100322,13 +101096,13 @@
       }
     }
 
-    private static class update_argsStandardSchemeFactory implements SchemeFactory {
+    private static class update_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public update_argsStandardScheme getScheme() {
         return new update_argsStandardScheme();
       }
     }
 
-    private static class update_argsStandardScheme extends StandardScheme<update_args> {
+    private static class update_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<update_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, update_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -100352,15 +101126,15 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map460 = iprot.readMapBegin();
-                  struct.cells = new HashMap<ByteBuffer,List<ColumnUpdate>>(2*_map460.size);
-                  ByteBuffer _key461;
-                  List<ColumnUpdate> _val462;
+                  struct.cells = new java.util.HashMap<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>(2*_map460.size);
+                  java.nio.ByteBuffer _key461;
+                  java.util.List<ColumnUpdate> _val462;
                   for (int _i463 = 0; _i463 < _map460.size; ++_i463)
                   {
                     _key461 = iprot.readBinary();
                     {
                       org.apache.thrift.protocol.TList _list464 = iprot.readListBegin();
-                      _val462 = new ArrayList<ColumnUpdate>(_list464.size);
+                      _val462 = new java.util.ArrayList<ColumnUpdate>(_list464.size);
                       ColumnUpdate _elem465;
                       for (int _i466 = 0; _i466 < _list464.size; ++_i466)
                       {
@@ -100403,7 +101177,7 @@
           oprot.writeFieldBegin(CELLS_FIELD_DESC);
           {
             oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.LIST, struct.cells.size()));
-            for (Map.Entry<ByteBuffer, List<ColumnUpdate>> _iter467 : struct.cells.entrySet())
+            for (java.util.Map.Entry<java.nio.ByteBuffer, java.util.List<ColumnUpdate>> _iter467 : struct.cells.entrySet())
             {
               oprot.writeBinary(_iter467.getKey());
               {
@@ -100425,18 +101199,18 @@
 
     }
 
-    private static class update_argsTupleSchemeFactory implements SchemeFactory {
+    private static class update_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public update_argsTupleScheme getScheme() {
         return new update_argsTupleScheme();
       }
     }
 
-    private static class update_argsTupleScheme extends TupleScheme<update_args> {
+    private static class update_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<update_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, update_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetWriter()) {
           optionals.set(0);
         }
@@ -100450,7 +101224,7 @@
         if (struct.isSetCells()) {
           {
             oprot.writeI32(struct.cells.size());
-            for (Map.Entry<ByteBuffer, List<ColumnUpdate>> _iter469 : struct.cells.entrySet())
+            for (java.util.Map.Entry<java.nio.ByteBuffer, java.util.List<ColumnUpdate>> _iter469 : struct.cells.entrySet())
             {
               oprot.writeBinary(_iter469.getKey());
               {
@@ -100467,8 +101241,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, update_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.writer = iprot.readString();
           struct.setWriterIsSet(true);
@@ -100476,15 +101250,15 @@
         if (incoming.get(1)) {
           {
             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);
-            ByteBuffer _key472;
-            List<ColumnUpdate> _val473;
+            struct.cells = new java.util.HashMap<java.nio.ByteBuffer,java.util.List<ColumnUpdate>>(2*_map471.size);
+            java.nio.ByteBuffer _key472;
+            java.util.List<ColumnUpdate> _val473;
             for (int _i474 = 0; _i474 < _map471.size; ++_i474)
             {
               _key472 = iprot.readBinary();
               {
                 org.apache.thrift.protocol.TList _list475 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
-                _val473 = new ArrayList<ColumnUpdate>(_list475.size);
+                _val473 = new java.util.ArrayList<ColumnUpdate>(_list475.size);
                 ColumnUpdate _elem476;
                 for (int _i477 = 0; _i477 < _list475.size; ++_i477)
                 {
@@ -100501,6 +101275,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class flush_args implements org.apache.thrift.TBase<flush_args, flush_args._Fields>, java.io.Serializable, Cloneable, Comparable<flush_args>   {
@@ -100508,22 +101285,19 @@
 
     private static final org.apache.thrift.protocol.TField WRITER_FIELD_DESC = new org.apache.thrift.protocol.TField("writer", 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 flush_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new flush_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new flush_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new flush_argsTupleSchemeFactory();
 
-    public String writer; // required
+    public java.lang.String writer; // 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 {
       WRITER((short)1, "writer");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -100546,21 +101320,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -100569,18 +101343,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.WRITER, new org.apache.thrift.meta_data.FieldMetaData("writer", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(flush_args.class, metaDataMap);
     }
 
@@ -100588,7 +101362,7 @@
     }
 
     public flush_args(
-      String writer)
+      java.lang.String writer)
     {
       this();
       this.writer = writer;
@@ -100612,11 +101386,11 @@
       this.writer = null;
     }
 
-    public String getWriter() {
+    public java.lang.String getWriter() {
       return this.writer;
     }
 
-    public flush_args setWriter(String writer) {
+    public flush_args setWriter(java.lang.String writer) {
       this.writer = writer;
       return this;
     }
@@ -100636,43 +101410,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case WRITER:
         if (value == null) {
           unsetWriter();
         } else {
-          setWriter((String)value);
+          setWriter((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case WRITER:
         return getWriter();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case WRITER:
         return isSetWriter();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof flush_args)
@@ -100683,6 +101457,8 @@
     public boolean equals(flush_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_writer = true && this.isSetWriter();
       boolean that_present_writer = true && that.isSetWriter();
@@ -100698,14 +101474,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_writer = true && (isSetWriter());
-      list.add(present_writer);
-      if (present_writer)
-        list.add(writer);
+      hashCode = hashCode * 8191 + ((isSetWriter()) ? 131071 : 524287);
+      if (isSetWriter())
+        hashCode = hashCode * 8191 + writer.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -100716,7 +101491,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetWriter()).compareTo(other.isSetWriter());
+      lastComparison = java.lang.Boolean.valueOf(isSetWriter()).compareTo(other.isSetWriter());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -100734,16 +101509,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("flush_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("flush_args(");
       boolean first = true;
 
       sb.append("writer:");
@@ -100770,7 +101545,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -100778,13 +101553,13 @@
       }
     }
 
-    private static class flush_argsStandardSchemeFactory implements SchemeFactory {
+    private static class flush_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public flush_argsStandardScheme getScheme() {
         return new flush_argsStandardScheme();
       }
     }
 
-    private static class flush_argsStandardScheme extends StandardScheme<flush_args> {
+    private static class flush_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<flush_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, flush_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -100830,18 +101605,18 @@
 
     }
 
-    private static class flush_argsTupleSchemeFactory implements SchemeFactory {
+    private static class flush_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public flush_argsTupleScheme getScheme() {
         return new flush_argsTupleScheme();
       }
     }
 
-    private static class flush_argsTupleScheme extends TupleScheme<flush_args> {
+    private static class flush_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<flush_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, flush_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetWriter()) {
           optionals.set(0);
         }
@@ -100853,8 +101628,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, flush_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.writer = iprot.readString();
           struct.setWriterIsSet(true);
@@ -100862,6 +101637,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class flush_result implements org.apache.thrift.TBase<flush_result, flush_result._Fields>, java.io.Serializable, Cloneable, Comparable<flush_result>   {
@@ -100870,11 +101648,8 @@
     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 flush_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new flush_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new flush_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new flush_resultTupleSchemeFactory();
 
     public UnknownWriter ouch1; // required
     public MutationsRejectedException ouch2; // required
@@ -100884,10 +101659,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -100912,21 +101687,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -100935,20 +101710,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, UnknownWriter.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, MutationsRejectedException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(flush_result.class, metaDataMap);
     }
 
@@ -101034,7 +101809,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -101055,7 +101830,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -101064,13 +101839,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -101079,11 +101854,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof flush_result)
@@ -101094,6 +101869,8 @@
     public boolean equals(flush_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -101118,19 +101895,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -101141,7 +101916,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -101151,7 +101926,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -101169,16 +101944,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("flush_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("flush_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -101213,7 +101988,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -101221,13 +101996,13 @@
       }
     }
 
-    private static class flush_resultStandardSchemeFactory implements SchemeFactory {
+    private static class flush_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public flush_resultStandardScheme getScheme() {
         return new flush_resultStandardScheme();
       }
     }
 
-    private static class flush_resultStandardScheme extends StandardScheme<flush_result> {
+    private static class flush_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<flush_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, flush_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -101288,18 +102063,18 @@
 
     }
 
-    private static class flush_resultTupleSchemeFactory implements SchemeFactory {
+    private static class flush_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public flush_resultTupleScheme getScheme() {
         return new flush_resultTupleScheme();
       }
     }
 
-    private static class flush_resultTupleScheme extends TupleScheme<flush_result> {
+    private static class flush_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<flush_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, flush_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -101317,8 +102092,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, flush_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new UnknownWriter();
           struct.ouch1.read(iprot);
@@ -101332,6 +102107,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class closeWriter_args implements org.apache.thrift.TBase<closeWriter_args, closeWriter_args._Fields>, java.io.Serializable, Cloneable, Comparable<closeWriter_args>   {
@@ -101339,22 +102117,19 @@
 
     private static final org.apache.thrift.protocol.TField WRITER_FIELD_DESC = new org.apache.thrift.protocol.TField("writer", 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 closeWriter_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new closeWriter_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new closeWriter_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new closeWriter_argsTupleSchemeFactory();
 
-    public String writer; // required
+    public java.lang.String writer; // 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 {
       WRITER((short)1, "writer");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -101377,21 +102152,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -101400,18 +102175,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.WRITER, new org.apache.thrift.meta_data.FieldMetaData("writer", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeWriter_args.class, metaDataMap);
     }
 
@@ -101419,7 +102194,7 @@
     }
 
     public closeWriter_args(
-      String writer)
+      java.lang.String writer)
     {
       this();
       this.writer = writer;
@@ -101443,11 +102218,11 @@
       this.writer = null;
     }
 
-    public String getWriter() {
+    public java.lang.String getWriter() {
       return this.writer;
     }
 
-    public closeWriter_args setWriter(String writer) {
+    public closeWriter_args setWriter(java.lang.String writer) {
       this.writer = writer;
       return this;
     }
@@ -101467,43 +102242,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case WRITER:
         if (value == null) {
           unsetWriter();
         } else {
-          setWriter((String)value);
+          setWriter((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case WRITER:
         return getWriter();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case WRITER:
         return isSetWriter();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof closeWriter_args)
@@ -101514,6 +102289,8 @@
     public boolean equals(closeWriter_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_writer = true && this.isSetWriter();
       boolean that_present_writer = true && that.isSetWriter();
@@ -101529,14 +102306,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_writer = true && (isSetWriter());
-      list.add(present_writer);
-      if (present_writer)
-        list.add(writer);
+      hashCode = hashCode * 8191 + ((isSetWriter()) ? 131071 : 524287);
+      if (isSetWriter())
+        hashCode = hashCode * 8191 + writer.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -101547,7 +102323,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetWriter()).compareTo(other.isSetWriter());
+      lastComparison = java.lang.Boolean.valueOf(isSetWriter()).compareTo(other.isSetWriter());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -101565,16 +102341,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("closeWriter_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeWriter_args(");
       boolean first = true;
 
       sb.append("writer:");
@@ -101601,7 +102377,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -101609,13 +102385,13 @@
       }
     }
 
-    private static class closeWriter_argsStandardSchemeFactory implements SchemeFactory {
+    private static class closeWriter_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeWriter_argsStandardScheme getScheme() {
         return new closeWriter_argsStandardScheme();
       }
     }
 
-    private static class closeWriter_argsStandardScheme extends StandardScheme<closeWriter_args> {
+    private static class closeWriter_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<closeWriter_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, closeWriter_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -101661,18 +102437,18 @@
 
     }
 
-    private static class closeWriter_argsTupleSchemeFactory implements SchemeFactory {
+    private static class closeWriter_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeWriter_argsTupleScheme getScheme() {
         return new closeWriter_argsTupleScheme();
       }
     }
 
-    private static class closeWriter_argsTupleScheme extends TupleScheme<closeWriter_args> {
+    private static class closeWriter_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<closeWriter_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, closeWriter_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetWriter()) {
           optionals.set(0);
         }
@@ -101684,8 +102460,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, closeWriter_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.writer = iprot.readString();
           struct.setWriterIsSet(true);
@@ -101693,6 +102469,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class closeWriter_result implements org.apache.thrift.TBase<closeWriter_result, closeWriter_result._Fields>, java.io.Serializable, Cloneable, Comparable<closeWriter_result>   {
@@ -101701,11 +102480,8 @@
     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 closeWriter_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new closeWriter_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new closeWriter_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new closeWriter_resultTupleSchemeFactory();
 
     public UnknownWriter ouch1; // required
     public MutationsRejectedException ouch2; // required
@@ -101715,10 +102491,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -101743,21 +102519,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -101766,20 +102542,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, UnknownWriter.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, MutationsRejectedException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeWriter_result.class, metaDataMap);
     }
 
@@ -101865,7 +102641,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -101886,7 +102662,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -101895,13 +102671,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -101910,11 +102686,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof closeWriter_result)
@@ -101925,6 +102701,8 @@
     public boolean equals(closeWriter_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -101949,19 +102727,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -101972,7 +102748,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -101982,7 +102758,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -102000,16 +102776,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("closeWriter_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeWriter_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -102044,7 +102820,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -102052,13 +102828,13 @@
       }
     }
 
-    private static class closeWriter_resultStandardSchemeFactory implements SchemeFactory {
+    private static class closeWriter_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeWriter_resultStandardScheme getScheme() {
         return new closeWriter_resultStandardScheme();
       }
     }
 
-    private static class closeWriter_resultStandardScheme extends StandardScheme<closeWriter_result> {
+    private static class closeWriter_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<closeWriter_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, closeWriter_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -102119,18 +102895,18 @@
 
     }
 
-    private static class closeWriter_resultTupleSchemeFactory implements SchemeFactory {
+    private static class closeWriter_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeWriter_resultTupleScheme getScheme() {
         return new closeWriter_resultTupleScheme();
       }
     }
 
-    private static class closeWriter_resultTupleScheme extends TupleScheme<closeWriter_result> {
+    private static class closeWriter_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<closeWriter_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, closeWriter_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -102148,8 +102924,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, closeWriter_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.ouch1 = new UnknownWriter();
           struct.ouch1.read(iprot);
@@ -102163,6 +102939,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class updateRowConditionally_args implements org.apache.thrift.TBase<updateRowConditionally_args, updateRowConditionally_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateRowConditionally_args>   {
@@ -102173,15 +102952,12 @@
     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)3);
     private static final org.apache.thrift.protocol.TField UPDATES_FIELD_DESC = new org.apache.thrift.protocol.TField("updates", 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 updateRowConditionally_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new updateRowConditionally_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateRowConditionally_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateRowConditionally_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
-    public ByteBuffer row; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
+    public java.nio.ByteBuffer row; // required
     public ConditionalUpdates updates; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -102191,10 +102967,10 @@
       ROW((short)3, "row"),
       UPDATES((short)4, "updates");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -102223,21 +102999,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -102246,15 +103022,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -102263,7 +103039,7 @@
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
       tmpMap.put(_Fields.UPDATES, new org.apache.thrift.meta_data.FieldMetaData("updates", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ConditionalUpdates.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateRowConditionally_args.class, metaDataMap);
     }
 
@@ -102271,9 +103047,9 @@
     }
 
     public updateRowConditionally_args(
-      ByteBuffer login,
-      String tableName,
-      ByteBuffer row,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
+      java.nio.ByteBuffer row,
       ConditionalUpdates updates)
     {
       this();
@@ -102318,16 +103094,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public updateRowConditionally_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public updateRowConditionally_args setLogin(ByteBuffer login) {
+    public updateRowConditionally_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -102347,11 +103123,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public updateRowConditionally_args setTableName(String tableName) {
+    public updateRowConditionally_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -102376,16 +103152,16 @@
       return row == null ? null : row.array();
     }
 
-    public ByteBuffer bufferForRow() {
+    public java.nio.ByteBuffer bufferForRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(row);
     }
 
     public updateRowConditionally_args setRow(byte[] row) {
-      this.row = row == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(row, row.length));
+      this.row = row == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(row.clone());
       return this;
     }
 
-    public updateRowConditionally_args setRow(ByteBuffer row) {
+    public updateRowConditionally_args setRow(java.nio.ByteBuffer row) {
       this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
       return this;
     }
@@ -102429,13 +103205,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -102443,7 +103223,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -102451,7 +103231,11 @@
         if (value == null) {
           unsetRow();
         } else {
-          setRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setRow((byte[])value);
+          } else {
+            setRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -102466,7 +103250,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -102481,13 +103265,13 @@
         return getUpdates();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -102500,11 +103284,11 @@
       case UPDATES:
         return isSetUpdates();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof updateRowConditionally_args)
@@ -102515,6 +103299,8 @@
     public boolean equals(updateRowConditionally_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -102557,29 +103343,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_row = true && (isSetRow());
-      list.add(present_row);
-      if (present_row)
-        list.add(row);
+      hashCode = hashCode * 8191 + ((isSetRow()) ? 131071 : 524287);
+      if (isSetRow())
+        hashCode = hashCode * 8191 + row.hashCode();
 
-      boolean present_updates = true && (isSetUpdates());
-      list.add(present_updates);
-      if (present_updates)
-        list.add(updates);
+      hashCode = hashCode * 8191 + ((isSetUpdates()) ? 131071 : 524287);
+      if (isSetUpdates())
+        hashCode = hashCode * 8191 + updates.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -102590,7 +103372,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -102600,7 +103382,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -102610,7 +103392,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetRow()).compareTo(other.isSetRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetRow()).compareTo(other.isSetRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -102620,7 +103402,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUpdates()).compareTo(other.isSetUpdates());
+      lastComparison = java.lang.Boolean.valueOf(isSetUpdates()).compareTo(other.isSetUpdates());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -102638,16 +103420,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("updateRowConditionally_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateRowConditionally_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -102701,7 +103483,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -102709,13 +103491,13 @@
       }
     }
 
-    private static class updateRowConditionally_argsStandardSchemeFactory implements SchemeFactory {
+    private static class updateRowConditionally_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateRowConditionally_argsStandardScheme getScheme() {
         return new updateRowConditionally_argsStandardScheme();
       }
     }
 
-    private static class updateRowConditionally_argsStandardScheme extends StandardScheme<updateRowConditionally_args> {
+    private static class updateRowConditionally_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateRowConditionally_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, updateRowConditionally_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -102801,18 +103583,18 @@
 
     }
 
-    private static class updateRowConditionally_argsTupleSchemeFactory implements SchemeFactory {
+    private static class updateRowConditionally_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateRowConditionally_argsTupleScheme getScheme() {
         return new updateRowConditionally_argsTupleScheme();
       }
     }
 
-    private static class updateRowConditionally_argsTupleScheme extends TupleScheme<updateRowConditionally_args> {
+    private static class updateRowConditionally_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateRowConditionally_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, updateRowConditionally_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -102842,8 +103624,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, updateRowConditionally_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -102864,6 +103646,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class updateRowConditionally_result implements org.apache.thrift.TBase<updateRowConditionally_result, updateRowConditionally_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateRowConditionally_result>   {
@@ -102874,11 +103659,8 @@
     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 updateRowConditionally_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new updateRowConditionally_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateRowConditionally_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateRowConditionally_resultTupleSchemeFactory();
 
     /**
      * 
@@ -102900,10 +103682,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -102932,21 +103714,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -102955,24 +103737,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConditionalStatus.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateRowConditionally_result.class, metaDataMap);
     }
 
@@ -103126,7 +103908,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
@@ -103163,7 +103945,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -103178,13 +103960,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -103197,11 +103979,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof updateRowConditionally_result)
@@ -103212,6 +103994,8 @@
     public boolean equals(updateRowConditionally_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -103254,29 +104038,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success.getValue());
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.getValue();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -103287,7 +104067,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -103297,7 +104077,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -103307,7 +104087,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -103317,7 +104097,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -103335,16 +104115,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("updateRowConditionally_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateRowConditionally_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -103395,7 +104175,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -103403,13 +104183,13 @@
       }
     }
 
-    private static class updateRowConditionally_resultStandardSchemeFactory implements SchemeFactory {
+    private static class updateRowConditionally_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateRowConditionally_resultStandardScheme getScheme() {
         return new updateRowConditionally_resultStandardScheme();
       }
     }
 
-    private static class updateRowConditionally_resultStandardScheme extends StandardScheme<updateRowConditionally_result> {
+    private static class updateRowConditionally_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateRowConditionally_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, updateRowConditionally_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -103497,18 +104277,18 @@
 
     }
 
-    private static class updateRowConditionally_resultTupleSchemeFactory implements SchemeFactory {
+    private static class updateRowConditionally_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateRowConditionally_resultTupleScheme getScheme() {
         return new updateRowConditionally_resultTupleScheme();
       }
     }
 
-    private static class updateRowConditionally_resultTupleScheme extends TupleScheme<updateRowConditionally_result> {
+    private static class updateRowConditionally_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateRowConditionally_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, updateRowConditionally_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -103538,8 +104318,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, updateRowConditionally_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = org.apache.accumulo.proxy.thrift.ConditionalStatus.findByValue(iprot.readI32());
           struct.setSuccessIsSet(true);
@@ -103562,6 +104342,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createConditionalWriter_args implements org.apache.thrift.TBase<createConditionalWriter_args, createConditionalWriter_args._Fields>, java.io.Serializable, Cloneable, Comparable<createConditionalWriter_args>   {
@@ -103571,14 +104354,11 @@
     private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)2);
     private static final org.apache.thrift.protocol.TField OPTIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("options", 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 createConditionalWriter_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createConditionalWriter_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createConditionalWriter_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createConditionalWriter_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String tableName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String tableName; // required
     public ConditionalWriterOptions options; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -103587,10 +104367,10 @@
       TABLE_NAME((short)2, "tableName"),
       OPTIONS((short)3, "options");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -103617,21 +104397,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -103640,22 +104420,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.OPTIONS, new org.apache.thrift.meta_data.FieldMetaData("options", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ConditionalWriterOptions.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createConditionalWriter_args.class, metaDataMap);
     }
 
@@ -103663,8 +104443,8 @@
     }
 
     public createConditionalWriter_args(
-      ByteBuffer login,
-      String tableName,
+      java.nio.ByteBuffer login,
+      java.lang.String tableName,
       ConditionalWriterOptions options)
     {
       this();
@@ -103704,16 +104484,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.ByteBuffer bufferForLogin() {
       return org.apache.thrift.TBaseHelper.copyBinary(login);
     }
 
     public createConditionalWriter_args setLogin(byte[] login) {
-      this.login = login == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(login, login.length));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public createConditionalWriter_args setLogin(ByteBuffer login) {
+    public createConditionalWriter_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -103733,11 +104513,11 @@
       }
     }
 
-    public String getTableName() {
+    public java.lang.String getTableName() {
       return this.tableName;
     }
 
-    public createConditionalWriter_args setTableName(String tableName) {
+    public createConditionalWriter_args setTableName(java.lang.String tableName) {
       this.tableName = tableName;
       return this;
     }
@@ -103781,13 +104561,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -103795,7 +104579,7 @@
         if (value == null) {
           unsetTableName();
         } else {
-          setTableName((String)value);
+          setTableName((java.lang.String)value);
         }
         break;
 
@@ -103810,7 +104594,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -103822,13 +104606,13 @@
         return getOptions();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -103839,11 +104623,11 @@
       case OPTIONS:
         return isSetOptions();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createConditionalWriter_args)
@@ -103854,6 +104638,8 @@
     public boolean equals(createConditionalWriter_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -103887,24 +104673,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_tableName = true && (isSetTableName());
-      list.add(present_tableName);
-      if (present_tableName)
-        list.add(tableName);
+      hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
+      if (isSetTableName())
+        hashCode = hashCode * 8191 + tableName.hashCode();
 
-      boolean present_options = true && (isSetOptions());
-      list.add(present_options);
-      if (present_options)
-        list.add(options);
+      hashCode = hashCode * 8191 + ((isSetOptions()) ? 131071 : 524287);
+      if (isSetOptions())
+        hashCode = hashCode * 8191 + options.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -103915,7 +104698,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -103925,7 +104708,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
+      lastComparison = java.lang.Boolean.valueOf(isSetTableName()).compareTo(other.isSetTableName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -103935,7 +104718,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
+      lastComparison = java.lang.Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -103953,16 +104736,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createConditionalWriter_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createConditionalWriter_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -104008,7 +104791,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -104016,13 +104799,13 @@
       }
     }
 
-    private static class createConditionalWriter_argsStandardSchemeFactory implements SchemeFactory {
+    private static class createConditionalWriter_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createConditionalWriter_argsStandardScheme getScheme() {
         return new createConditionalWriter_argsStandardScheme();
       }
     }
 
-    private static class createConditionalWriter_argsStandardScheme extends StandardScheme<createConditionalWriter_args> {
+    private static class createConditionalWriter_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createConditionalWriter_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createConditionalWriter_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -104095,18 +104878,18 @@
 
     }
 
-    private static class createConditionalWriter_argsTupleSchemeFactory implements SchemeFactory {
+    private static class createConditionalWriter_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createConditionalWriter_argsTupleScheme getScheme() {
         return new createConditionalWriter_argsTupleScheme();
       }
     }
 
-    private static class createConditionalWriter_argsTupleScheme extends TupleScheme<createConditionalWriter_args> {
+    private static class createConditionalWriter_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createConditionalWriter_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createConditionalWriter_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -104130,8 +104913,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createConditionalWriter_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(3);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -104148,6 +104931,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createConditionalWriter_result implements org.apache.thrift.TBase<createConditionalWriter_result, createConditionalWriter_result._Fields>, java.io.Serializable, Cloneable, Comparable<createConditionalWriter_result>   {
@@ -104158,13 +104944,10 @@
     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 createConditionalWriter_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new createConditionalWriter_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createConditionalWriter_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createConditionalWriter_resultTupleSchemeFactory();
 
-    public String success; // required
+    public java.lang.String success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public TableNotFoundException ouch3; // required
@@ -104176,10 +104959,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -104208,21 +104991,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -104231,24 +105014,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TableNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createConditionalWriter_result.class, metaDataMap);
     }
 
@@ -104256,7 +105039,7 @@
     }
 
     public createConditionalWriter_result(
-      String success,
+      java.lang.String success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       TableNotFoundException ouch3)
@@ -104298,11 +105081,11 @@
       this.ouch3 = null;
     }
 
-    public String getSuccess() {
+    public java.lang.String getSuccess() {
       return this.success;
     }
 
-    public createConditionalWriter_result setSuccess(String success) {
+    public createConditionalWriter_result setSuccess(java.lang.String success) {
       this.success = success;
       return this;
     }
@@ -104394,13 +105177,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((String)value);
+          setSuccess((java.lang.String)value);
         }
         break;
 
@@ -104431,7 +105214,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -104446,13 +105229,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -104465,11 +105248,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createConditionalWriter_result)
@@ -104480,6 +105263,8 @@
     public boolean equals(createConditionalWriter_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -104522,29 +105307,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -104555,7 +105336,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -104565,7 +105346,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -104575,7 +105356,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -104585,7 +105366,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -104603,16 +105384,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createConditionalWriter_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createConditionalWriter_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -104663,7 +105444,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -104671,13 +105452,13 @@
       }
     }
 
-    private static class createConditionalWriter_resultStandardSchemeFactory implements SchemeFactory {
+    private static class createConditionalWriter_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createConditionalWriter_resultStandardScheme getScheme() {
         return new createConditionalWriter_resultStandardScheme();
       }
     }
 
-    private static class createConditionalWriter_resultStandardScheme extends StandardScheme<createConditionalWriter_result> {
+    private static class createConditionalWriter_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createConditionalWriter_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, createConditionalWriter_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -104765,18 +105546,18 @@
 
     }
 
-    private static class createConditionalWriter_resultTupleSchemeFactory implements SchemeFactory {
+    private static class createConditionalWriter_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createConditionalWriter_resultTupleScheme getScheme() {
         return new createConditionalWriter_resultTupleScheme();
       }
     }
 
-    private static class createConditionalWriter_resultTupleScheme extends TupleScheme<createConditionalWriter_result> {
+    private static class createConditionalWriter_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createConditionalWriter_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, createConditionalWriter_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -104806,8 +105587,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, createConditionalWriter_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = iprot.readString();
           struct.setSuccessIsSet(true);
@@ -104830,6 +105611,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class updateRowsConditionally_args implements org.apache.thrift.TBase<updateRowsConditionally_args, updateRowsConditionally_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateRowsConditionally_args>   {
@@ -104838,24 +105622,21 @@
     private static final org.apache.thrift.protocol.TField CONDITIONAL_WRITER_FIELD_DESC = new org.apache.thrift.protocol.TField("conditionalWriter", org.apache.thrift.protocol.TType.STRING, (short)1);
     private static final org.apache.thrift.protocol.TField UPDATES_FIELD_DESC = new org.apache.thrift.protocol.TField("updates", org.apache.thrift.protocol.TType.MAP, (short)2);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new updateRowsConditionally_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new updateRowsConditionally_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateRowsConditionally_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateRowsConditionally_argsTupleSchemeFactory();
 
-    public String conditionalWriter; // required
-    public Map<ByteBuffer,ConditionalUpdates> updates; // required
+    public java.lang.String conditionalWriter; // required
+    public java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates; // 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 {
       CONDITIONAL_WRITER((short)1, "conditionalWriter"),
       UPDATES((short)2, "updates");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -104880,21 +105661,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -104903,22 +105684,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.CONDITIONAL_WRITER, new org.apache.thrift.meta_data.FieldMetaData("conditionalWriter", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
       tmpMap.put(_Fields.UPDATES, new org.apache.thrift.meta_data.FieldMetaData("updates", 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              , true), 
               new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ConditionalUpdates.class))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateRowsConditionally_args.class, metaDataMap);
     }
 
@@ -104926,8 +105707,8 @@
     }
 
     public updateRowsConditionally_args(
-      String conditionalWriter,
-      Map<ByteBuffer,ConditionalUpdates> updates)
+      java.lang.String conditionalWriter,
+      java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates)
     {
       this();
       this.conditionalWriter = conditionalWriter;
@@ -104942,13 +105723,13 @@
         this.conditionalWriter = other.conditionalWriter;
       }
       if (other.isSetUpdates()) {
-        Map<ByteBuffer,ConditionalUpdates> __this__updates = new HashMap<ByteBuffer,ConditionalUpdates>(other.updates.size());
-        for (Map.Entry<ByteBuffer, ConditionalUpdates> other_element : other.updates.entrySet()) {
+        java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> __this__updates = new java.util.HashMap<java.nio.ByteBuffer,ConditionalUpdates>(other.updates.size());
+        for (java.util.Map.Entry<java.nio.ByteBuffer, ConditionalUpdates> other_element : other.updates.entrySet()) {
 
-          ByteBuffer other_element_key = other_element.getKey();
+          java.nio.ByteBuffer other_element_key = other_element.getKey();
           ConditionalUpdates other_element_value = other_element.getValue();
 
-          ByteBuffer __this__updates_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
+          java.nio.ByteBuffer __this__updates_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
 
           ConditionalUpdates __this__updates_copy_value = new ConditionalUpdates(other_element_value);
 
@@ -104968,11 +105749,11 @@
       this.updates = null;
     }
 
-    public String getConditionalWriter() {
+    public java.lang.String getConditionalWriter() {
       return this.conditionalWriter;
     }
 
-    public updateRowsConditionally_args setConditionalWriter(String conditionalWriter) {
+    public updateRowsConditionally_args setConditionalWriter(java.lang.String conditionalWriter) {
       this.conditionalWriter = conditionalWriter;
       return this;
     }
@@ -104996,18 +105777,18 @@
       return (this.updates == null) ? 0 : this.updates.size();
     }
 
-    public void putToUpdates(ByteBuffer key, ConditionalUpdates val) {
+    public void putToUpdates(java.nio.ByteBuffer key, ConditionalUpdates val) {
       if (this.updates == null) {
-        this.updates = new HashMap<ByteBuffer,ConditionalUpdates>();
+        this.updates = new java.util.HashMap<java.nio.ByteBuffer,ConditionalUpdates>();
       }
       this.updates.put(key, val);
     }
 
-    public Map<ByteBuffer,ConditionalUpdates> getUpdates() {
+    public java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> getUpdates() {
       return this.updates;
     }
 
-    public updateRowsConditionally_args setUpdates(Map<ByteBuffer,ConditionalUpdates> updates) {
+    public updateRowsConditionally_args setUpdates(java.util.Map<java.nio.ByteBuffer,ConditionalUpdates> updates) {
       this.updates = updates;
       return this;
     }
@@ -105027,13 +105808,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case CONDITIONAL_WRITER:
         if (value == null) {
           unsetConditionalWriter();
         } else {
-          setConditionalWriter((String)value);
+          setConditionalWriter((java.lang.String)value);
         }
         break;
 
@@ -105041,14 +105822,14 @@
         if (value == null) {
           unsetUpdates();
         } else {
-          setUpdates((Map<ByteBuffer,ConditionalUpdates>)value);
+          setUpdates((java.util.Map<java.nio.ByteBuffer,ConditionalUpdates>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case CONDITIONAL_WRITER:
         return getConditionalWriter();
@@ -105057,13 +105838,13 @@
         return getUpdates();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -105072,11 +105853,11 @@
       case UPDATES:
         return isSetUpdates();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof updateRowsConditionally_args)
@@ -105087,6 +105868,8 @@
     public boolean equals(updateRowsConditionally_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_conditionalWriter = true && this.isSetConditionalWriter();
       boolean that_present_conditionalWriter = true && that.isSetConditionalWriter();
@@ -105111,19 +105894,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_conditionalWriter = true && (isSetConditionalWriter());
-      list.add(present_conditionalWriter);
-      if (present_conditionalWriter)
-        list.add(conditionalWriter);
+      hashCode = hashCode * 8191 + ((isSetConditionalWriter()) ? 131071 : 524287);
+      if (isSetConditionalWriter())
+        hashCode = hashCode * 8191 + conditionalWriter.hashCode();
 
-      boolean present_updates = true && (isSetUpdates());
-      list.add(present_updates);
-      if (present_updates)
-        list.add(updates);
+      hashCode = hashCode * 8191 + ((isSetUpdates()) ? 131071 : 524287);
+      if (isSetUpdates())
+        hashCode = hashCode * 8191 + updates.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -105134,7 +105915,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetConditionalWriter()).compareTo(other.isSetConditionalWriter());
+      lastComparison = java.lang.Boolean.valueOf(isSetConditionalWriter()).compareTo(other.isSetConditionalWriter());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -105144,7 +105925,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetUpdates()).compareTo(other.isSetUpdates());
+      lastComparison = java.lang.Boolean.valueOf(isSetUpdates()).compareTo(other.isSetUpdates());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -105162,16 +105943,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("updateRowsConditionally_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateRowsConditionally_args(");
       boolean first = true;
 
       sb.append("conditionalWriter:");
@@ -105206,7 +105987,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -105214,13 +105995,13 @@
       }
     }
 
-    private static class updateRowsConditionally_argsStandardSchemeFactory implements SchemeFactory {
+    private static class updateRowsConditionally_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateRowsConditionally_argsStandardScheme getScheme() {
         return new updateRowsConditionally_argsStandardScheme();
       }
     }
 
-    private static class updateRowsConditionally_argsStandardScheme extends StandardScheme<updateRowsConditionally_args> {
+    private static class updateRowsConditionally_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateRowsConditionally_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, updateRowsConditionally_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -105244,8 +106025,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map478 = iprot.readMapBegin();
-                  struct.updates = new HashMap<ByteBuffer,ConditionalUpdates>(2*_map478.size);
-                  ByteBuffer _key479;
+                  struct.updates = new java.util.HashMap<java.nio.ByteBuffer,ConditionalUpdates>(2*_map478.size);
+                  java.nio.ByteBuffer _key479;
                   ConditionalUpdates _val480;
                   for (int _i481 = 0; _i481 < _map478.size; ++_i481)
                   {
@@ -105285,7 +106066,7 @@
           oprot.writeFieldBegin(UPDATES_FIELD_DESC);
           {
             oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, struct.updates.size()));
-            for (Map.Entry<ByteBuffer, ConditionalUpdates> _iter482 : struct.updates.entrySet())
+            for (java.util.Map.Entry<java.nio.ByteBuffer, ConditionalUpdates> _iter482 : struct.updates.entrySet())
             {
               oprot.writeBinary(_iter482.getKey());
               _iter482.getValue().write(oprot);
@@ -105300,18 +106081,18 @@
 
     }
 
-    private static class updateRowsConditionally_argsTupleSchemeFactory implements SchemeFactory {
+    private static class updateRowsConditionally_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateRowsConditionally_argsTupleScheme getScheme() {
         return new updateRowsConditionally_argsTupleScheme();
       }
     }
 
-    private static class updateRowsConditionally_argsTupleScheme extends TupleScheme<updateRowsConditionally_args> {
+    private static class updateRowsConditionally_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateRowsConditionally_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, updateRowsConditionally_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetConditionalWriter()) {
           optionals.set(0);
         }
@@ -105325,7 +106106,7 @@
         if (struct.isSetUpdates()) {
           {
             oprot.writeI32(struct.updates.size());
-            for (Map.Entry<ByteBuffer, ConditionalUpdates> _iter483 : struct.updates.entrySet())
+            for (java.util.Map.Entry<java.nio.ByteBuffer, ConditionalUpdates> _iter483 : struct.updates.entrySet())
             {
               oprot.writeBinary(_iter483.getKey());
               _iter483.getValue().write(oprot);
@@ -105336,8 +106117,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, updateRowsConditionally_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.conditionalWriter = iprot.readString();
           struct.setConditionalWriterIsSet(true);
@@ -105345,8 +106126,8 @@
         if (incoming.get(1)) {
           {
             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);
-            ByteBuffer _key485;
+            struct.updates = new java.util.HashMap<java.nio.ByteBuffer,ConditionalUpdates>(2*_map484.size);
+            java.nio.ByteBuffer _key485;
             ConditionalUpdates _val486;
             for (int _i487 = 0; _i487 < _map484.size; ++_i487)
             {
@@ -105361,6 +106142,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class updateRowsConditionally_result implements org.apache.thrift.TBase<updateRowsConditionally_result, updateRowsConditionally_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateRowsConditionally_result>   {
@@ -105371,13 +106155,10 @@
     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 updateRowsConditionally_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new updateRowsConditionally_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateRowsConditionally_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateRowsConditionally_resultTupleSchemeFactory();
 
-    public Map<ByteBuffer,ConditionalStatus> success; // required
+    public java.util.Map<java.nio.ByteBuffer,ConditionalStatus> success; // required
     public UnknownWriter ouch1; // required
     public AccumuloException ouch2; // required
     public AccumuloSecurityException ouch3; // required
@@ -105389,10 +106170,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -105421,21 +106202,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -105444,26 +106225,26 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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              , true), 
               new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConditionalStatus.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, UnknownWriter.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateRowsConditionally_result.class, metaDataMap);
     }
 
@@ -105471,7 +106252,7 @@
     }
 
     public updateRowsConditionally_result(
-      Map<ByteBuffer,ConditionalStatus> success,
+      java.util.Map<java.nio.ByteBuffer,ConditionalStatus> success,
       UnknownWriter ouch1,
       AccumuloException ouch2,
       AccumuloSecurityException ouch3)
@@ -105488,13 +106269,13 @@
      */
     public updateRowsConditionally_result(updateRowsConditionally_result other) {
       if (other.isSetSuccess()) {
-        Map<ByteBuffer,ConditionalStatus> __this__success = new HashMap<ByteBuffer,ConditionalStatus>(other.success.size());
-        for (Map.Entry<ByteBuffer, ConditionalStatus> other_element : other.success.entrySet()) {
+        java.util.Map<java.nio.ByteBuffer,ConditionalStatus> __this__success = new java.util.HashMap<java.nio.ByteBuffer,ConditionalStatus>(other.success.size());
+        for (java.util.Map.Entry<java.nio.ByteBuffer, ConditionalStatus> other_element : other.success.entrySet()) {
 
-          ByteBuffer other_element_key = other_element.getKey();
+          java.nio.ByteBuffer other_element_key = other_element.getKey();
           ConditionalStatus other_element_value = other_element.getValue();
 
-          ByteBuffer __this__success_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
+          java.nio.ByteBuffer __this__success_copy_key = org.apache.thrift.TBaseHelper.copyBinary(other_element_key);
 
           ConditionalStatus __this__success_copy_value = other_element_value;
 
@@ -105529,18 +106310,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(ByteBuffer key, ConditionalStatus val) {
+    public void putToSuccess(java.nio.ByteBuffer key, ConditionalStatus val) {
       if (this.success == null) {
-        this.success = new HashMap<ByteBuffer,ConditionalStatus>();
+        this.success = new java.util.HashMap<java.nio.ByteBuffer,ConditionalStatus>();
       }
       this.success.put(key, val);
     }
 
-    public Map<ByteBuffer,ConditionalStatus> getSuccess() {
+    public java.util.Map<java.nio.ByteBuffer,ConditionalStatus> getSuccess() {
       return this.success;
     }
 
-    public updateRowsConditionally_result setSuccess(Map<ByteBuffer,ConditionalStatus> success) {
+    public updateRowsConditionally_result setSuccess(java.util.Map<java.nio.ByteBuffer,ConditionalStatus> success) {
       this.success = success;
       return this;
     }
@@ -105632,13 +106413,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<ByteBuffer,ConditionalStatus>)value);
+          setSuccess((java.util.Map<java.nio.ByteBuffer,ConditionalStatus>)value);
         }
         break;
 
@@ -105669,7 +106450,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -105684,13 +106465,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -105703,11 +106484,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof updateRowsConditionally_result)
@@ -105718,6 +106499,8 @@
     public boolean equals(updateRowsConditionally_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -105760,29 +106543,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -105793,7 +106572,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -105803,7 +106582,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -105813,7 +106592,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -105823,7 +106602,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -105841,16 +106620,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("updateRowsConditionally_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateRowsConditionally_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -105901,7 +106680,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -105909,13 +106688,13 @@
       }
     }
 
-    private static class updateRowsConditionally_resultStandardSchemeFactory implements SchemeFactory {
+    private static class updateRowsConditionally_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateRowsConditionally_resultStandardScheme getScheme() {
         return new updateRowsConditionally_resultStandardScheme();
       }
     }
 
-    private static class updateRowsConditionally_resultStandardScheme extends StandardScheme<updateRowsConditionally_result> {
+    private static class updateRowsConditionally_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateRowsConditionally_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, updateRowsConditionally_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -105931,8 +106710,8 @@
               if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
                 {
                   org.apache.thrift.protocol.TMap _map488 = iprot.readMapBegin();
-                  struct.success = new HashMap<ByteBuffer,ConditionalStatus>(2*_map488.size);
-                  ByteBuffer _key489;
+                  struct.success = new java.util.HashMap<java.nio.ByteBuffer,ConditionalStatus>(2*_map488.size);
+                  java.nio.ByteBuffer _key489;
                   ConditionalStatus _val490;
                   for (int _i491 = 0; _i491 < _map488.size; ++_i491)
                   {
@@ -105993,7 +106772,7 @@
           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<ByteBuffer, ConditionalStatus> _iter492 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.nio.ByteBuffer, ConditionalStatus> _iter492 : struct.success.entrySet())
             {
               oprot.writeBinary(_iter492.getKey());
               oprot.writeI32(_iter492.getValue().getValue());
@@ -106023,18 +106802,18 @@
 
     }
 
-    private static class updateRowsConditionally_resultTupleSchemeFactory implements SchemeFactory {
+    private static class updateRowsConditionally_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public updateRowsConditionally_resultTupleScheme getScheme() {
         return new updateRowsConditionally_resultTupleScheme();
       }
     }
 
-    private static class updateRowsConditionally_resultTupleScheme extends TupleScheme<updateRowsConditionally_result> {
+    private static class updateRowsConditionally_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateRowsConditionally_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, updateRowsConditionally_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -106051,7 +106830,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<ByteBuffer, ConditionalStatus> _iter493 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.nio.ByteBuffer, ConditionalStatus> _iter493 : struct.success.entrySet())
             {
               oprot.writeBinary(_iter493.getKey());
               oprot.writeI32(_iter493.getValue().getValue());
@@ -106071,13 +106850,13 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, updateRowsConditionally_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(4);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           {
             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);
-            ByteBuffer _key495;
+            struct.success = new java.util.HashMap<java.nio.ByteBuffer,ConditionalStatus>(2*_map494.size);
+            java.nio.ByteBuffer _key495;
             ConditionalStatus _val496;
             for (int _i497 = 0; _i497 < _map494.size; ++_i497)
             {
@@ -106106,6 +106885,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class closeConditionalWriter_args implements org.apache.thrift.TBase<closeConditionalWriter_args, closeConditionalWriter_args._Fields>, java.io.Serializable, Cloneable, Comparable<closeConditionalWriter_args>   {
@@ -106113,22 +106895,19 @@
 
     private static final org.apache.thrift.protocol.TField CONDITIONAL_WRITER_FIELD_DESC = new org.apache.thrift.protocol.TField("conditionalWriter", 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 closeConditionalWriter_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new closeConditionalWriter_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new closeConditionalWriter_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new closeConditionalWriter_argsTupleSchemeFactory();
 
-    public String conditionalWriter; // required
+    public java.lang.String conditionalWriter; // 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 {
       CONDITIONAL_WRITER((short)1, "conditionalWriter");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -106151,21 +106930,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -106174,18 +106953,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.CONDITIONAL_WRITER, new org.apache.thrift.meta_data.FieldMetaData("conditionalWriter", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeConditionalWriter_args.class, metaDataMap);
     }
 
@@ -106193,7 +106972,7 @@
     }
 
     public closeConditionalWriter_args(
-      String conditionalWriter)
+      java.lang.String conditionalWriter)
     {
       this();
       this.conditionalWriter = conditionalWriter;
@@ -106217,11 +106996,11 @@
       this.conditionalWriter = null;
     }
 
-    public String getConditionalWriter() {
+    public java.lang.String getConditionalWriter() {
       return this.conditionalWriter;
     }
 
-    public closeConditionalWriter_args setConditionalWriter(String conditionalWriter) {
+    public closeConditionalWriter_args setConditionalWriter(java.lang.String conditionalWriter) {
       this.conditionalWriter = conditionalWriter;
       return this;
     }
@@ -106241,43 +107020,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case CONDITIONAL_WRITER:
         if (value == null) {
           unsetConditionalWriter();
         } else {
-          setConditionalWriter((String)value);
+          setConditionalWriter((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case CONDITIONAL_WRITER:
         return getConditionalWriter();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case CONDITIONAL_WRITER:
         return isSetConditionalWriter();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof closeConditionalWriter_args)
@@ -106288,6 +107067,8 @@
     public boolean equals(closeConditionalWriter_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_conditionalWriter = true && this.isSetConditionalWriter();
       boolean that_present_conditionalWriter = true && that.isSetConditionalWriter();
@@ -106303,14 +107084,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_conditionalWriter = true && (isSetConditionalWriter());
-      list.add(present_conditionalWriter);
-      if (present_conditionalWriter)
-        list.add(conditionalWriter);
+      hashCode = hashCode * 8191 + ((isSetConditionalWriter()) ? 131071 : 524287);
+      if (isSetConditionalWriter())
+        hashCode = hashCode * 8191 + conditionalWriter.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -106321,7 +107101,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetConditionalWriter()).compareTo(other.isSetConditionalWriter());
+      lastComparison = java.lang.Boolean.valueOf(isSetConditionalWriter()).compareTo(other.isSetConditionalWriter());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -106339,16 +107119,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("closeConditionalWriter_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeConditionalWriter_args(");
       boolean first = true;
 
       sb.append("conditionalWriter:");
@@ -106375,7 +107155,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -106383,13 +107163,13 @@
       }
     }
 
-    private static class closeConditionalWriter_argsStandardSchemeFactory implements SchemeFactory {
+    private static class closeConditionalWriter_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeConditionalWriter_argsStandardScheme getScheme() {
         return new closeConditionalWriter_argsStandardScheme();
       }
     }
 
-    private static class closeConditionalWriter_argsStandardScheme extends StandardScheme<closeConditionalWriter_args> {
+    private static class closeConditionalWriter_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<closeConditionalWriter_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, closeConditionalWriter_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -106435,18 +107215,18 @@
 
     }
 
-    private static class closeConditionalWriter_argsTupleSchemeFactory implements SchemeFactory {
+    private static class closeConditionalWriter_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeConditionalWriter_argsTupleScheme getScheme() {
         return new closeConditionalWriter_argsTupleScheme();
       }
     }
 
-    private static class closeConditionalWriter_argsTupleScheme extends TupleScheme<closeConditionalWriter_args> {
+    private static class closeConditionalWriter_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<closeConditionalWriter_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, closeConditionalWriter_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetConditionalWriter()) {
           optionals.set(0);
         }
@@ -106458,8 +107238,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, closeConditionalWriter_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.conditionalWriter = iprot.readString();
           struct.setConditionalWriterIsSet(true);
@@ -106467,27 +107247,27 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class closeConditionalWriter_result implements org.apache.thrift.TBase<closeConditionalWriter_result, closeConditionalWriter_result._Fields>, java.io.Serializable, Cloneable, Comparable<closeConditionalWriter_result>   {
     private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("closeConditionalWriter_result");
 
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new closeConditionalWriter_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new closeConditionalWriter_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new closeConditionalWriter_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new closeConditionalWriter_resultTupleSchemeFactory();
 
 
     /** 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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -106508,21 +107288,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -106531,14 +107311,14 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(closeConditionalWriter_result.class, metaDataMap);
     }
 
@@ -106559,30 +107339,30 @@
     public void clear() {
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof closeConditionalWriter_result)
@@ -106593,15 +107373,17 @@
     public boolean equals(closeConditionalWriter_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       return true;
     }
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -106620,16 +107402,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("closeConditionalWriter_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("closeConditionalWriter_result(");
       boolean first = true;
 
       sb.append(")");
@@ -106649,7 +107431,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -106657,13 +107439,13 @@
       }
     }
 
-    private static class closeConditionalWriter_resultStandardSchemeFactory implements SchemeFactory {
+    private static class closeConditionalWriter_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeConditionalWriter_resultStandardScheme getScheme() {
         return new closeConditionalWriter_resultStandardScheme();
       }
     }
 
-    private static class closeConditionalWriter_resultStandardScheme extends StandardScheme<closeConditionalWriter_result> {
+    private static class closeConditionalWriter_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<closeConditionalWriter_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, closeConditionalWriter_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -106696,25 +107478,28 @@
 
     }
 
-    private static class closeConditionalWriter_resultTupleSchemeFactory implements SchemeFactory {
+    private static class closeConditionalWriter_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public closeConditionalWriter_resultTupleScheme getScheme() {
         return new closeConditionalWriter_resultTupleScheme();
       }
     }
 
-    private static class closeConditionalWriter_resultTupleScheme extends TupleScheme<closeConditionalWriter_result> {
+    private static class closeConditionalWriter_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<closeConditionalWriter_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, closeConditionalWriter_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
       }
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, closeConditionalWriter_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getRowRange_args implements org.apache.thrift.TBase<getRowRange_args, getRowRange_args._Fields>, java.io.Serializable, Cloneable, Comparable<getRowRange_args>   {
@@ -106722,22 +107507,19 @@
 
     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);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new getRowRange_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getRowRange_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getRowRange_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getRowRange_argsTupleSchemeFactory();
 
-    public ByteBuffer row; // required
+    public java.nio.ByteBuffer row; // 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 {
       ROW((short)1, "row");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -106760,21 +107542,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -106783,18 +107565,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.ROW, new org.apache.thrift.meta_data.FieldMetaData("row", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getRowRange_args.class, metaDataMap);
     }
 
@@ -106802,7 +107584,7 @@
     }
 
     public getRowRange_args(
-      ByteBuffer row)
+      java.nio.ByteBuffer row)
     {
       this();
       this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
@@ -106831,16 +107613,16 @@
       return row == null ? null : row.array();
     }
 
-    public ByteBuffer bufferForRow() {
+    public java.nio.ByteBuffer bufferForRow() {
       return org.apache.thrift.TBaseHelper.copyBinary(row);
     }
 
     public getRowRange_args setRow(byte[] row) {
-      this.row = row == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(row, row.length));
+      this.row = row == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(row.clone());
       return this;
     }
 
-    public getRowRange_args setRow(ByteBuffer row) {
+    public getRowRange_args setRow(java.nio.ByteBuffer row) {
       this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
       return this;
     }
@@ -106860,43 +107642,47 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case ROW:
         if (value == null) {
           unsetRow();
         } else {
-          setRow((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setRow((byte[])value);
+          } else {
+            setRow((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case ROW:
         return getRow();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case ROW:
         return isSetRow();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getRowRange_args)
@@ -106907,6 +107693,8 @@
     public boolean equals(getRowRange_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_row = true && this.isSetRow();
       boolean that_present_row = true && that.isSetRow();
@@ -106922,14 +107710,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_row = true && (isSetRow());
-      list.add(present_row);
-      if (present_row)
-        list.add(row);
+      hashCode = hashCode * 8191 + ((isSetRow()) ? 131071 : 524287);
+      if (isSetRow())
+        hashCode = hashCode * 8191 + row.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -106940,7 +107727,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetRow()).compareTo(other.isSetRow());
+      lastComparison = java.lang.Boolean.valueOf(isSetRow()).compareTo(other.isSetRow());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -106958,16 +107745,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getRowRange_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getRowRange_args(");
       boolean first = true;
 
       sb.append("row:");
@@ -106994,7 +107781,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -107002,13 +107789,13 @@
       }
     }
 
-    private static class getRowRange_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getRowRange_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getRowRange_argsStandardScheme getScheme() {
         return new getRowRange_argsStandardScheme();
       }
     }
 
-    private static class getRowRange_argsStandardScheme extends StandardScheme<getRowRange_args> {
+    private static class getRowRange_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getRowRange_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getRowRange_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -107054,18 +107841,18 @@
 
     }
 
-    private static class getRowRange_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getRowRange_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getRowRange_argsTupleScheme getScheme() {
         return new getRowRange_argsTupleScheme();
       }
     }
 
-    private static class getRowRange_argsTupleScheme extends TupleScheme<getRowRange_args> {
+    private static class getRowRange_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getRowRange_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getRowRange_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetRow()) {
           optionals.set(0);
         }
@@ -107077,8 +107864,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getRowRange_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.row = iprot.readBinary();
           struct.setRowIsSet(true);
@@ -107086,6 +107873,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getRowRange_result implements org.apache.thrift.TBase<getRowRange_result, getRowRange_result._Fields>, java.io.Serializable, Cloneable, Comparable<getRowRange_result>   {
@@ -107093,11 +107883,8 @@
 
     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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new getRowRange_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getRowRange_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getRowRange_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getRowRange_resultTupleSchemeFactory();
 
     public Range success; // required
 
@@ -107105,10 +107892,10 @@
     public enum _Fields implements org.apache.thrift.TFieldIdEnum {
       SUCCESS((short)0, "success");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -107131,21 +107918,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -107154,18 +107941,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, Range.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getRowRange_result.class, metaDataMap);
     }
 
@@ -107221,7 +108008,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
@@ -107234,30 +108021,30 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SUCCESS:
         return isSetSuccess();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getRowRange_result)
@@ -107268,6 +108055,8 @@
     public boolean equals(getRowRange_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -107283,14 +108072,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -107301,7 +108089,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -107319,16 +108107,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getRowRange_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getRowRange_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -107358,7 +108146,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -107366,13 +108154,13 @@
       }
     }
 
-    private static class getRowRange_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getRowRange_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getRowRange_resultStandardScheme getScheme() {
         return new getRowRange_resultStandardScheme();
       }
     }
 
-    private static class getRowRange_resultStandardScheme extends StandardScheme<getRowRange_result> {
+    private static class getRowRange_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getRowRange_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getRowRange_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -107419,18 +108207,18 @@
 
     }
 
-    private static class getRowRange_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getRowRange_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getRowRange_resultTupleScheme getScheme() {
         return new getRowRange_resultTupleScheme();
       }
     }
 
-    private static class getRowRange_resultTupleScheme extends TupleScheme<getRowRange_result> {
+    private static class getRowRange_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getRowRange_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getRowRange_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -107442,8 +108230,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getRowRange_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.success = new Range();
           struct.success.read(iprot);
@@ -107452,6 +108240,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getFollowing_args implements org.apache.thrift.TBase<getFollowing_args, getFollowing_args._Fields>, java.io.Serializable, Cloneable, Comparable<getFollowing_args>   {
@@ -107460,11 +108251,8 @@
     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);
     private static final org.apache.thrift.protocol.TField PART_FIELD_DESC = new org.apache.thrift.protocol.TField("part", org.apache.thrift.protocol.TType.I32, (short)2);
 
-    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new getFollowing_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getFollowing_argsTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getFollowing_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getFollowing_argsTupleSchemeFactory();
 
     public Key key; // required
     /**
@@ -107482,10 +108270,10 @@
        */
       PART((short)2, "part");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -107510,21 +108298,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -107533,20 +108321,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Key.class)));
       tmpMap.put(_Fields.PART, new org.apache.thrift.meta_data.FieldMetaData("part", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, PartialKey.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getFollowing_args.class, metaDataMap);
     }
 
@@ -107640,7 +108428,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case KEY:
         if (value == null) {
@@ -107661,7 +108449,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case KEY:
         return getKey();
@@ -107670,13 +108458,13 @@
         return getPart();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -107685,11 +108473,11 @@
       case PART:
         return isSetPart();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getFollowing_args)
@@ -107700,6 +108488,8 @@
     public boolean equals(getFollowing_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_key = true && this.isSetKey();
       boolean that_present_key = true && that.isSetKey();
@@ -107724,19 +108514,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_key = true && (isSetKey());
-      list.add(present_key);
-      if (present_key)
-        list.add(key);
+      hashCode = hashCode * 8191 + ((isSetKey()) ? 131071 : 524287);
+      if (isSetKey())
+        hashCode = hashCode * 8191 + key.hashCode();
 
-      boolean present_part = true && (isSetPart());
-      list.add(present_part);
-      if (present_part)
-        list.add(part.getValue());
+      hashCode = hashCode * 8191 + ((isSetPart()) ? 131071 : 524287);
+      if (isSetPart())
+        hashCode = hashCode * 8191 + part.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -107747,7 +108535,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
+      lastComparison = java.lang.Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -107757,7 +108545,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetPart()).compareTo(other.isSetPart());
+      lastComparison = java.lang.Boolean.valueOf(isSetPart()).compareTo(other.isSetPart());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -107775,16 +108563,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getFollowing_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getFollowing_args(");
       boolean first = true;
 
       sb.append("key:");
@@ -107822,7 +108610,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -107830,13 +108618,13 @@
       }
     }
 
-    private static class getFollowing_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getFollowing_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getFollowing_argsStandardScheme getScheme() {
         return new getFollowing_argsStandardScheme();
       }
     }
 
-    private static class getFollowing_argsStandardScheme extends StandardScheme<getFollowing_args> {
+    private static class getFollowing_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getFollowing_args> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getFollowing_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -107896,18 +108684,18 @@
 
     }
 
-    private static class getFollowing_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getFollowing_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getFollowing_argsTupleScheme getScheme() {
         return new getFollowing_argsTupleScheme();
       }
     }
 
-    private static class getFollowing_argsTupleScheme extends TupleScheme<getFollowing_args> {
+    private static class getFollowing_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getFollowing_args> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getFollowing_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetKey()) {
           optionals.set(0);
         }
@@ -107925,8 +108713,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getFollowing_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(2);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.key = new Key();
           struct.key.read(iprot);
@@ -107939,6 +108727,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getFollowing_result implements org.apache.thrift.TBase<getFollowing_result, getFollowing_result._Fields>, java.io.Serializable, Cloneable, Comparable<getFollowing_result>   {
@@ -107946,11 +108737,8 @@
 
     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 Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-    static {
-      schemes.put(StandardScheme.class, new getFollowing_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new getFollowing_resultTupleSchemeFactory());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getFollowing_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getFollowing_resultTupleSchemeFactory();
 
     public Key success; // required
 
@@ -107958,10 +108746,10 @@
     public enum _Fields implements org.apache.thrift.TFieldIdEnum {
       SUCCESS((short)0, "success");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -107984,21 +108772,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -108007,18 +108795,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, Key.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getFollowing_result.class, metaDataMap);
     }
 
@@ -108074,7 +108862,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
@@ -108087,30 +108875,30 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SUCCESS:
         return isSetSuccess();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getFollowing_result)
@@ -108121,6 +108909,8 @@
     public boolean equals(getFollowing_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -108136,14 +108926,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -108154,7 +108943,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -108172,16 +108961,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getFollowing_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getFollowing_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -108211,7 +109000,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -108219,13 +109008,13 @@
       }
     }
 
-    private static class getFollowing_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getFollowing_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getFollowing_resultStandardScheme getScheme() {
         return new getFollowing_resultStandardScheme();
       }
     }
 
-    private static class getFollowing_resultStandardScheme extends StandardScheme<getFollowing_result> {
+    private static class getFollowing_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getFollowing_result> {
 
       public void read(org.apache.thrift.protocol.TProtocol iprot, getFollowing_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
@@ -108272,18 +109061,18 @@
 
     }
 
-    private static class getFollowing_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getFollowing_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getFollowing_resultTupleScheme getScheme() {
         return new getFollowing_resultTupleScheme();
       }
     }
 
-    private static class getFollowing_resultTupleScheme extends TupleScheme<getFollowing_result> {
+    private static class getFollowing_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getFollowing_result> {
 
       @Override
       public void write(org.apache.thrift.protocol.TProtocol prot, getFollowing_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol oprot = (TTupleProtocol) prot;
-        BitSet optionals = new BitSet();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -108295,8 +109084,8 @@
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, getFollowing_result struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(1);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.success = new Key();
           struct.success.read(iprot);
@@ -108305,27 +109094,27 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new systemNamespace_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = 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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -108346,21 +109135,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -108369,14 +109158,14 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(systemNamespace_args.class, metaDataMap);
     }
 
@@ -108397,30 +109186,30 @@
     public void clear() {
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof systemNamespace_args)
@@ -108431,15 +109220,17 @@
     public boolean equals(systemNamespace_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       return true;
     }
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -108458,16 +109249,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("systemNamespace_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("systemNamespace_args(");
       boolean first = true;
 
       sb.append(")");
@@ -108487,7 +109278,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -108495,13 +109286,13 @@
       }
     }
 
-    private static class systemNamespace_argsStandardSchemeFactory implements SchemeFactory {
+    private static class systemNamespace_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public systemNamespace_argsStandardScheme getScheme() {
         return new systemNamespace_argsStandardScheme();
       }
     }
 
-    private static class systemNamespace_argsStandardScheme extends StandardScheme<systemNamespace_args> {
+    private static class systemNamespace_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -108534,25 +109325,28 @@
 
     }
 
-    private static class systemNamespace_argsTupleSchemeFactory implements SchemeFactory {
+    private static class systemNamespace_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public systemNamespace_argsTupleScheme getScheme() {
         return new systemNamespace_argsTupleScheme();
       }
     }
 
-    private static class systemNamespace_argsTupleScheme extends TupleScheme<systemNamespace_args> {
+    private static class systemNamespace_argsTupleScheme extends org.apache.thrift.scheme.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;
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
       }
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, systemNamespace_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class systemNamespace_result implements org.apache.thrift.TBase<systemNamespace_result, systemNamespace_result._Fields>, java.io.Serializable, Cloneable, Comparable<systemNamespace_result>   {
@@ -108560,22 +109354,19 @@
 
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new systemNamespace_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new systemNamespace_resultTupleSchemeFactory();
 
-    public String success; // required
+    public java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -108598,21 +109389,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -108621,18 +109412,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(systemNamespace_result.class, metaDataMap);
     }
 
@@ -108640,7 +109431,7 @@
     }
 
     public systemNamespace_result(
-      String success)
+      java.lang.String success)
     {
       this();
       this.success = success;
@@ -108664,11 +109455,11 @@
       this.success = null;
     }
 
-    public String getSuccess() {
+    public java.lang.String getSuccess() {
       return this.success;
     }
 
-    public systemNamespace_result setSuccess(String success) {
+    public systemNamespace_result setSuccess(java.lang.String success) {
       this.success = success;
       return this;
     }
@@ -108688,43 +109479,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((String)value);
+          setSuccess((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SUCCESS:
         return isSetSuccess();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof systemNamespace_result)
@@ -108735,6 +109526,8 @@
     public boolean equals(systemNamespace_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -108750,14 +109543,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -108768,7 +109560,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -108786,16 +109578,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("systemNamespace_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("systemNamespace_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -108822,7 +109614,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -108830,13 +109622,13 @@
       }
     }
 
-    private static class systemNamespace_resultStandardSchemeFactory implements SchemeFactory {
+    private static class systemNamespace_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public systemNamespace_resultStandardScheme getScheme() {
         return new systemNamespace_resultStandardScheme();
       }
     }
 
-    private static class systemNamespace_resultStandardScheme extends StandardScheme<systemNamespace_result> {
+    private static class systemNamespace_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -108882,18 +109674,18 @@
 
     }
 
-    private static class systemNamespace_resultTupleSchemeFactory implements SchemeFactory {
+    private static class systemNamespace_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public systemNamespace_resultTupleScheme getScheme() {
         return new systemNamespace_resultTupleScheme();
       }
     }
 
-    private static class systemNamespace_resultTupleScheme extends TupleScheme<systemNamespace_result> {
+    private static class systemNamespace_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -108905,8 +109697,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.success = iprot.readString();
           struct.setSuccessIsSet(true);
@@ -108914,27 +109706,27 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new defaultNamespace_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = 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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -108955,21 +109747,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -108978,14 +109770,14 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(defaultNamespace_args.class, metaDataMap);
     }
 
@@ -109006,30 +109798,30 @@
     public void clear() {
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof defaultNamespace_args)
@@ -109040,15 +109832,17 @@
     public boolean equals(defaultNamespace_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       return true;
     }
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -109067,16 +109861,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("defaultNamespace_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("defaultNamespace_args(");
       boolean first = true;
 
       sb.append(")");
@@ -109096,7 +109890,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -109104,13 +109898,13 @@
       }
     }
 
-    private static class defaultNamespace_argsStandardSchemeFactory implements SchemeFactory {
+    private static class defaultNamespace_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public defaultNamespace_argsStandardScheme getScheme() {
         return new defaultNamespace_argsStandardScheme();
       }
     }
 
-    private static class defaultNamespace_argsStandardScheme extends StandardScheme<defaultNamespace_args> {
+    private static class defaultNamespace_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -109143,25 +109937,28 @@
 
     }
 
-    private static class defaultNamespace_argsTupleSchemeFactory implements SchemeFactory {
+    private static class defaultNamespace_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public defaultNamespace_argsTupleScheme getScheme() {
         return new defaultNamespace_argsTupleScheme();
       }
     }
 
-    private static class defaultNamespace_argsTupleScheme extends TupleScheme<defaultNamespace_args> {
+    private static class defaultNamespace_argsTupleScheme extends org.apache.thrift.scheme.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;
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
       }
 
       @Override
       public void read(org.apache.thrift.protocol.TProtocol prot, defaultNamespace_args struct) throws org.apache.thrift.TException {
-        TTupleProtocol iprot = (TTupleProtocol) prot;
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class defaultNamespace_result implements org.apache.thrift.TBase<defaultNamespace_result, defaultNamespace_result._Fields>, java.io.Serializable, Cloneable, Comparable<defaultNamespace_result>   {
@@ -109169,22 +109966,19 @@
 
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new defaultNamespace_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new defaultNamespace_resultTupleSchemeFactory();
 
-    public String success; // required
+    public java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -109207,21 +110001,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -109230,18 +110024,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(defaultNamespace_result.class, metaDataMap);
     }
 
@@ -109249,7 +110043,7 @@
     }
 
     public defaultNamespace_result(
-      String success)
+      java.lang.String success)
     {
       this();
       this.success = success;
@@ -109273,11 +110067,11 @@
       this.success = null;
     }
 
-    public String getSuccess() {
+    public java.lang.String getSuccess() {
       return this.success;
     }
 
-    public defaultNamespace_result setSuccess(String success) {
+    public defaultNamespace_result setSuccess(java.lang.String success) {
       this.success = success;
       return this;
     }
@@ -109297,43 +110091,43 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((String)value);
+          setSuccess((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case SUCCESS:
         return isSetSuccess();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof defaultNamespace_result)
@@ -109344,6 +110138,8 @@
     public boolean equals(defaultNamespace_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -109359,14 +110155,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -109377,7 +110172,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -109395,16 +110190,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("defaultNamespace_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("defaultNamespace_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -109431,7 +110226,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -109439,13 +110234,13 @@
       }
     }
 
-    private static class defaultNamespace_resultStandardSchemeFactory implements SchemeFactory {
+    private static class defaultNamespace_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public defaultNamespace_resultStandardScheme getScheme() {
         return new defaultNamespace_resultStandardScheme();
       }
     }
 
-    private static class defaultNamespace_resultStandardScheme extends StandardScheme<defaultNamespace_result> {
+    private static class defaultNamespace_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -109491,18 +110286,18 @@
 
     }
 
-    private static class defaultNamespace_resultTupleSchemeFactory implements SchemeFactory {
+    private static class defaultNamespace_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public defaultNamespace_resultTupleScheme getScheme() {
         return new defaultNamespace_resultTupleScheme();
       }
     }
 
-    private static class defaultNamespace_resultTupleScheme extends TupleScheme<defaultNamespace_result> {
+    private static class defaultNamespace_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -109514,8 +110309,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.success = iprot.readString();
           struct.setSuccessIsSet(true);
@@ -109523,6 +110318,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listNamespaces_args implements org.apache.thrift.TBase<listNamespaces_args, listNamespaces_args._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaces_args>   {
@@ -109530,22 +110328,19 @@
 
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listNamespaces_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listNamespaces_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
+    public java.nio.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -109568,21 +110363,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -109591,18 +110386,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaces_args.class, metaDataMap);
     }
 
@@ -109610,7 +110405,7 @@
     }
 
     public listNamespaces_args(
-      ByteBuffer login)
+      java.nio.ByteBuffer login)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -109639,16 +110434,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public listNamespaces_args setLogin(ByteBuffer login) {
+    public listNamespaces_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -109668,43 +110463,47 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case LOGIN:
         return isSetLogin();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listNamespaces_args)
@@ -109715,6 +110514,8 @@
     public boolean equals(listNamespaces_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -109730,14 +110531,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -109748,7 +110548,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -109766,16 +110566,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listNamespaces_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaces_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -109802,7 +110602,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -109810,13 +110610,13 @@
       }
     }
 
-    private static class listNamespaces_argsStandardSchemeFactory implements SchemeFactory {
+    private static class listNamespaces_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaces_argsStandardScheme getScheme() {
         return new listNamespaces_argsStandardScheme();
       }
     }
 
-    private static class listNamespaces_argsStandardScheme extends StandardScheme<listNamespaces_args> {
+    private static class listNamespaces_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -109862,18 +110662,18 @@
 
     }
 
-    private static class listNamespaces_argsTupleSchemeFactory implements SchemeFactory {
+    private static class listNamespaces_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaces_argsTupleScheme getScheme() {
         return new listNamespaces_argsTupleScheme();
       }
     }
 
-    private static class listNamespaces_argsTupleScheme extends TupleScheme<listNamespaces_args> {
+    private static class listNamespaces_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -109885,8 +110685,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -109894,6 +110694,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listNamespaces_result implements org.apache.thrift.TBase<listNamespaces_result, listNamespaces_result._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaces_result>   {
@@ -109903,13 +110706,10 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listNamespaces_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listNamespaces_resultTupleSchemeFactory();
 
-    public List<String> success; // required
+    public java.util.List<java.lang.String> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
 
@@ -109919,10 +110719,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -109949,21 +110749,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -109972,23 +110772,23 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaces_result.class, metaDataMap);
     }
 
@@ -109996,7 +110796,7 @@
     }
 
     public listNamespaces_result(
-      List<String> success,
+      java.util.List<java.lang.String> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2)
     {
@@ -110011,7 +110811,7 @@
      */
     public listNamespaces_result(listNamespaces_result other) {
       if (other.isSetSuccess()) {
-        List<String> __this__success = new ArrayList<String>(other.success);
+        java.util.List<java.lang.String> __this__success = new java.util.ArrayList<java.lang.String>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -110037,22 +110837,22 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public java.util.Iterator<String> getSuccessIterator() {
+    public java.util.Iterator<java.lang.String> getSuccessIterator() {
       return (this.success == null) ? null : this.success.iterator();
     }
 
-    public void addToSuccess(String elem) {
+    public void addToSuccess(java.lang.String elem) {
       if (this.success == null) {
-        this.success = new ArrayList<String>();
+        this.success = new java.util.ArrayList<java.lang.String>();
       }
       this.success.add(elem);
     }
 
-    public List<String> getSuccess() {
+    public java.util.List<java.lang.String> getSuccess() {
       return this.success;
     }
 
-    public listNamespaces_result setSuccess(List<String> success) {
+    public listNamespaces_result setSuccess(java.util.List<java.lang.String> success) {
       this.success = success;
       return this;
     }
@@ -110120,13 +110920,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((List<String>)value);
+          setSuccess((java.util.List<java.lang.String>)value);
         }
         break;
 
@@ -110149,7 +110949,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -110161,13 +110961,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -110178,11 +110978,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listNamespaces_result)
@@ -110193,6 +110993,8 @@
     public boolean equals(listNamespaces_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -110226,24 +111028,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -110254,7 +111053,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -110264,7 +111063,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -110274,7 +111073,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -110292,16 +111091,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listNamespaces_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaces_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -110344,7 +111143,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -110352,13 +111151,13 @@
       }
     }
 
-    private static class listNamespaces_resultStandardSchemeFactory implements SchemeFactory {
+    private static class listNamespaces_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaces_resultStandardScheme getScheme() {
         return new listNamespaces_resultStandardScheme();
       }
     }
 
-    private static class listNamespaces_resultStandardScheme extends StandardScheme<listNamespaces_result> {
+    private static class listNamespaces_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -110374,8 +111173,8 @@
               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;
+                  struct.success = new java.util.ArrayList<java.lang.String>(_list498.size);
+                  java.lang.String _elem499;
                   for (int _i500 = 0; _i500 < _list498.size; ++_i500)
                   {
                     _elem499 = iprot.readString();
@@ -110425,7 +111224,7 @@
           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)
+            for (java.lang.String _iter501 : struct.success)
             {
               oprot.writeString(_iter501);
             }
@@ -110449,18 +111248,18 @@
 
     }
 
-    private static class listNamespaces_resultTupleSchemeFactory implements SchemeFactory {
+    private static class listNamespaces_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaces_resultTupleScheme getScheme() {
         return new listNamespaces_resultTupleScheme();
       }
     }
 
-    private static class listNamespaces_resultTupleScheme extends TupleScheme<listNamespaces_result> {
+    private static class listNamespaces_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -110474,7 +111273,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (String _iter502 : struct.success)
+            for (java.lang.String _iter502 : struct.success)
             {
               oprot.writeString(_iter502);
             }
@@ -110490,13 +111289,13 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.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;
+            struct.success = new java.util.ArrayList<java.lang.String>(_list503.size);
+            java.lang.String _elem504;
             for (int _i505 = 0; _i505 < _list503.size; ++_i505)
             {
               _elem504 = iprot.readString();
@@ -110518,6 +111317,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class namespaceExists_args implements org.apache.thrift.TBase<namespaceExists_args, namespaceExists_args._Fields>, java.io.Serializable, Cloneable, Comparable<namespaceExists_args>   {
@@ -110526,24 +111328,21 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new namespaceExists_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new namespaceExists_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -110568,21 +111367,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -110591,20 +111390,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(namespaceExists_args.class, metaDataMap);
     }
 
@@ -110612,8 +111411,8 @@
     }
 
     public namespaceExists_args(
-      ByteBuffer login,
-      String namespaceName)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -110647,16 +111446,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public namespaceExists_args setLogin(ByteBuffer login) {
+    public namespaceExists_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -110676,11 +111475,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public namespaceExists_args setNamespaceName(String namespaceName) {
+    public namespaceExists_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -110700,13 +111499,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -110714,14 +111517,14 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -110730,13 +111533,13 @@
         return getNamespaceName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -110745,11 +111548,11 @@
       case NAMESPACE_NAME:
         return isSetNamespaceName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof namespaceExists_args)
@@ -110760,6 +111563,8 @@
     public boolean equals(namespaceExists_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -110784,19 +111589,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -110807,7 +111610,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -110817,7 +111620,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -110835,16 +111638,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("namespaceExists_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("namespaceExists_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -110879,7 +111682,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -110887,13 +111690,13 @@
       }
     }
 
-    private static class namespaceExists_argsStandardSchemeFactory implements SchemeFactory {
+    private static class namespaceExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public namespaceExists_argsStandardScheme getScheme() {
         return new namespaceExists_argsStandardScheme();
       }
     }
 
-    private static class namespaceExists_argsStandardScheme extends StandardScheme<namespaceExists_args> {
+    private static class namespaceExists_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -110952,18 +111755,18 @@
 
     }
 
-    private static class namespaceExists_argsTupleSchemeFactory implements SchemeFactory {
+    private static class namespaceExists_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public namespaceExists_argsTupleScheme getScheme() {
         return new namespaceExists_argsTupleScheme();
       }
     }
 
-    private static class namespaceExists_argsTupleScheme extends TupleScheme<namespaceExists_args> {
+    private static class namespaceExists_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -110981,8 +111784,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -110994,6 +111797,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class namespaceExists_result implements org.apache.thrift.TBase<namespaceExists_result, namespaceExists_result._Fields>, java.io.Serializable, Cloneable, Comparable<namespaceExists_result>   {
@@ -111003,11 +111809,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new namespaceExists_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new namespaceExists_resultTupleSchemeFactory();
 
     public boolean success; // required
     public AccumuloException ouch1; // required
@@ -111019,10 +111822,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -111049,21 +111852,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -111072,7 +111875,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -111080,16 +111883,16 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(namespaceExists_result.class, metaDataMap);
     }
 
@@ -111145,16 +111948,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public AccumuloException getOuch1() {
@@ -111205,13 +112008,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Boolean)value);
+          setSuccess((java.lang.Boolean)value);
         }
         break;
 
@@ -111234,7 +112037,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return isSuccess();
@@ -111246,13 +112049,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -111263,11 +112066,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof namespaceExists_result)
@@ -111278,6 +112081,8 @@
     public boolean equals(namespaceExists_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -111311,24 +112116,19 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -111339,7 +112139,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -111349,7 +112149,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -111359,7 +112159,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -111377,16 +112177,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("namespaceExists_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("namespaceExists_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -111425,7 +112225,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -111435,13 +112235,13 @@
       }
     }
 
-    private static class namespaceExists_resultStandardSchemeFactory implements SchemeFactory {
+    private static class namespaceExists_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public namespaceExists_resultStandardScheme getScheme() {
         return new namespaceExists_resultStandardScheme();
       }
     }
 
-    private static class namespaceExists_resultStandardScheme extends StandardScheme<namespaceExists_result> {
+    private static class namespaceExists_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -111515,18 +112315,18 @@
 
     }
 
-    private static class namespaceExists_resultTupleSchemeFactory implements SchemeFactory {
+    private static class namespaceExists_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public namespaceExists_resultTupleScheme getScheme() {
         return new namespaceExists_resultTupleScheme();
       }
     }
 
-    private static class namespaceExists_resultTupleScheme extends TupleScheme<namespaceExists_result> {
+    private static class namespaceExists_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -111550,8 +112350,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.success = iprot.readBool();
           struct.setSuccessIsSet(true);
@@ -111569,6 +112369,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createNamespace_args implements org.apache.thrift.TBase<createNamespace_args, createNamespace_args._Fields>, java.io.Serializable, Cloneable, Comparable<createNamespace_args>   {
@@ -111577,24 +112380,21 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createNamespace_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createNamespace_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -111619,21 +112419,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -111642,20 +112442,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createNamespace_args.class, metaDataMap);
     }
 
@@ -111663,8 +112463,8 @@
     }
 
     public createNamespace_args(
-      ByteBuffer login,
-      String namespaceName)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -111698,16 +112498,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public createNamespace_args setLogin(ByteBuffer login) {
+    public createNamespace_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -111727,11 +112527,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public createNamespace_args setNamespaceName(String namespaceName) {
+    public createNamespace_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -111751,13 +112551,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -111765,14 +112569,14 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -111781,13 +112585,13 @@
         return getNamespaceName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -111796,11 +112600,11 @@
       case NAMESPACE_NAME:
         return isSetNamespaceName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createNamespace_args)
@@ -111811,6 +112615,8 @@
     public boolean equals(createNamespace_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -111835,19 +112641,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -111858,7 +112662,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -111868,7 +112672,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -111886,16 +112690,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createNamespace_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createNamespace_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -111930,7 +112734,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -111938,13 +112742,13 @@
       }
     }
 
-    private static class createNamespace_argsStandardSchemeFactory implements SchemeFactory {
+    private static class createNamespace_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createNamespace_argsStandardScheme getScheme() {
         return new createNamespace_argsStandardScheme();
       }
     }
 
-    private static class createNamespace_argsStandardScheme extends StandardScheme<createNamespace_args> {
+    private static class createNamespace_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -112003,18 +112807,18 @@
 
     }
 
-    private static class createNamespace_argsTupleSchemeFactory implements SchemeFactory {
+    private static class createNamespace_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createNamespace_argsTupleScheme getScheme() {
         return new createNamespace_argsTupleScheme();
       }
     }
 
-    private static class createNamespace_argsTupleScheme extends TupleScheme<createNamespace_args> {
+    private static class createNamespace_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -112032,8 +112836,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -112045,6 +112849,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class createNamespace_result implements org.apache.thrift.TBase<createNamespace_result, createNamespace_result._Fields>, java.io.Serializable, Cloneable, Comparable<createNamespace_result>   {
@@ -112054,11 +112861,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createNamespace_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createNamespace_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -112070,10 +112874,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -112100,21 +112904,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -112123,22 +112927,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceExistsException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createNamespace_result.class, metaDataMap);
     }
 
@@ -112254,7 +113058,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -112283,7 +113087,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -112295,13 +113099,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -112312,11 +113116,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof createNamespace_result)
@@ -112327,6 +113131,8 @@
     public boolean equals(createNamespace_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -112360,24 +113166,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -112388,7 +113191,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -112398,7 +113201,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -112408,7 +113211,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -112426,16 +113229,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("createNamespace_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("createNamespace_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -112478,7 +113281,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -112486,13 +113289,13 @@
       }
     }
 
-    private static class createNamespace_resultStandardSchemeFactory implements SchemeFactory {
+    private static class createNamespace_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createNamespace_resultStandardScheme getScheme() {
         return new createNamespace_resultStandardScheme();
       }
     }
 
-    private static class createNamespace_resultStandardScheme extends StandardScheme<createNamespace_result> {
+    private static class createNamespace_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -112567,18 +113370,18 @@
 
     }
 
-    private static class createNamespace_resultTupleSchemeFactory implements SchemeFactory {
+    private static class createNamespace_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public createNamespace_resultTupleScheme getScheme() {
         return new createNamespace_resultTupleScheme();
       }
     }
 
-    private static class createNamespace_resultTupleScheme extends TupleScheme<createNamespace_result> {
+    private static class createNamespace_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -112602,8 +113405,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -112622,6 +113425,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class deleteNamespace_args implements org.apache.thrift.TBase<deleteNamespace_args, deleteNamespace_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteNamespace_args>   {
@@ -112630,24 +113436,21 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteNamespace_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteNamespace_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -112672,21 +113475,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -112695,20 +113498,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteNamespace_args.class, metaDataMap);
     }
 
@@ -112716,8 +113519,8 @@
     }
 
     public deleteNamespace_args(
-      ByteBuffer login,
-      String namespaceName)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -112751,16 +113554,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public deleteNamespace_args setLogin(ByteBuffer login) {
+    public deleteNamespace_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -112780,11 +113583,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public deleteNamespace_args setNamespaceName(String namespaceName) {
+    public deleteNamespace_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -112804,13 +113607,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -112818,14 +113625,14 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -112834,13 +113641,13 @@
         return getNamespaceName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -112849,11 +113656,11 @@
       case NAMESPACE_NAME:
         return isSetNamespaceName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof deleteNamespace_args)
@@ -112864,6 +113671,8 @@
     public boolean equals(deleteNamespace_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -112888,19 +113697,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -112911,7 +113718,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -112921,7 +113728,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -112939,16 +113746,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("deleteNamespace_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteNamespace_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -112983,7 +113790,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -112991,13 +113798,13 @@
       }
     }
 
-    private static class deleteNamespace_argsStandardSchemeFactory implements SchemeFactory {
+    private static class deleteNamespace_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteNamespace_argsStandardScheme getScheme() {
         return new deleteNamespace_argsStandardScheme();
       }
     }
 
-    private static class deleteNamespace_argsStandardScheme extends StandardScheme<deleteNamespace_args> {
+    private static class deleteNamespace_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -113056,18 +113863,18 @@
 
     }
 
-    private static class deleteNamespace_argsTupleSchemeFactory implements SchemeFactory {
+    private static class deleteNamespace_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteNamespace_argsTupleScheme getScheme() {
         return new deleteNamespace_argsTupleScheme();
       }
     }
 
-    private static class deleteNamespace_argsTupleScheme extends TupleScheme<deleteNamespace_args> {
+    private static class deleteNamespace_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -113085,8 +113892,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -113098,6 +113905,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class deleteNamespace_result implements org.apache.thrift.TBase<deleteNamespace_result, deleteNamespace_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteNamespace_result>   {
@@ -113108,11 +113918,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteNamespace_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteNamespace_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -113126,10 +113933,10 @@
       OUCH3((short)3, "ouch3"),
       OUCH4((short)4, "ouch4");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -113158,21 +113965,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -113181,24 +113988,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotEmptyException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteNamespace_result.class, metaDataMap);
     }
 
@@ -113344,7 +114151,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -113381,7 +114188,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -113396,13 +114203,13 @@
         return getOuch4();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -113415,11 +114222,11 @@
       case OUCH4:
         return isSetOuch4();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof deleteNamespace_result)
@@ -113430,6 +114237,8 @@
     public boolean equals(deleteNamespace_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -113472,29 +114281,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      boolean present_ouch4 = true && (isSetOuch4());
-      list.add(present_ouch4);
-      if (present_ouch4)
-        list.add(ouch4);
+      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
+      if (isSetOuch4())
+        hashCode = hashCode * 8191 + ouch4.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -113505,7 +114310,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -113515,7 +114320,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -113525,7 +114330,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -113535,7 +114340,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -113553,16 +114358,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("deleteNamespace_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteNamespace_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -113613,7 +114418,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -113621,13 +114426,13 @@
       }
     }
 
-    private static class deleteNamespace_resultStandardSchemeFactory implements SchemeFactory {
+    private static class deleteNamespace_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteNamespace_resultStandardScheme getScheme() {
         return new deleteNamespace_resultStandardScheme();
       }
     }
 
-    private static class deleteNamespace_resultStandardScheme extends StandardScheme<deleteNamespace_result> {
+    private static class deleteNamespace_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -113716,18 +114521,18 @@
 
     }
 
-    private static class deleteNamespace_resultTupleSchemeFactory implements SchemeFactory {
+    private static class deleteNamespace_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public deleteNamespace_resultTupleScheme getScheme() {
         return new deleteNamespace_resultTupleScheme();
       }
     }
 
-    private static class deleteNamespace_resultTupleScheme extends TupleScheme<deleteNamespace_result> {
+    private static class deleteNamespace_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -113757,8 +114562,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -113782,6 +114587,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class renameNamespace_args implements org.apache.thrift.TBase<renameNamespace_args, renameNamespace_args._Fields>, java.io.Serializable, Cloneable, Comparable<renameNamespace_args>   {
@@ -113791,15 +114599,12 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new renameNamespace_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new renameNamespace_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String oldNamespaceName; // required
-    public String newNamespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String oldNamespaceName; // required
+    public java.lang.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 {
@@ -113807,10 +114612,10 @@
       OLD_NAMESPACE_NAME((short)2, "oldNamespaceName"),
       NEW_NAMESPACE_NAME((short)3, "newNamespaceName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -113837,21 +114642,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -113860,22 +114665,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(renameNamespace_args.class, metaDataMap);
     }
 
@@ -113883,9 +114688,9 @@
     }
 
     public renameNamespace_args(
-      ByteBuffer login,
-      String oldNamespaceName,
-      String newNamespaceName)
+      java.nio.ByteBuffer login,
+      java.lang.String oldNamespaceName,
+      java.lang.String newNamespaceName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -113924,16 +114729,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public renameNamespace_args setLogin(ByteBuffer login) {
+    public renameNamespace_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -113953,11 +114758,11 @@
       }
     }
 
-    public String getOldNamespaceName() {
+    public java.lang.String getOldNamespaceName() {
       return this.oldNamespaceName;
     }
 
-    public renameNamespace_args setOldNamespaceName(String oldNamespaceName) {
+    public renameNamespace_args setOldNamespaceName(java.lang.String oldNamespaceName) {
       this.oldNamespaceName = oldNamespaceName;
       return this;
     }
@@ -113977,11 +114782,11 @@
       }
     }
 
-    public String getNewNamespaceName() {
+    public java.lang.String getNewNamespaceName() {
       return this.newNamespaceName;
     }
 
-    public renameNamespace_args setNewNamespaceName(String newNamespaceName) {
+    public renameNamespace_args setNewNamespaceName(java.lang.String newNamespaceName) {
       this.newNamespaceName = newNamespaceName;
       return this;
     }
@@ -114001,13 +114806,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -114015,7 +114824,7 @@
         if (value == null) {
           unsetOldNamespaceName();
         } else {
-          setOldNamespaceName((String)value);
+          setOldNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -114023,14 +114832,14 @@
         if (value == null) {
           unsetNewNamespaceName();
         } else {
-          setNewNamespaceName((String)value);
+          setNewNamespaceName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -114042,13 +114851,13 @@
         return getNewNamespaceName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -114059,11 +114868,11 @@
       case NEW_NAMESPACE_NAME:
         return isSetNewNamespaceName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof renameNamespace_args)
@@ -114074,6 +114883,8 @@
     public boolean equals(renameNamespace_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -114107,24 +114918,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_oldNamespaceName = true && (isSetOldNamespaceName());
-      list.add(present_oldNamespaceName);
-      if (present_oldNamespaceName)
-        list.add(oldNamespaceName);
+      hashCode = hashCode * 8191 + ((isSetOldNamespaceName()) ? 131071 : 524287);
+      if (isSetOldNamespaceName())
+        hashCode = hashCode * 8191 + oldNamespaceName.hashCode();
 
-      boolean present_newNamespaceName = true && (isSetNewNamespaceName());
-      list.add(present_newNamespaceName);
-      if (present_newNamespaceName)
-        list.add(newNamespaceName);
+      hashCode = hashCode * 8191 + ((isSetNewNamespaceName()) ? 131071 : 524287);
+      if (isSetNewNamespaceName())
+        hashCode = hashCode * 8191 + newNamespaceName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -114135,7 +114943,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -114145,7 +114953,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOldNamespaceName()).compareTo(other.isSetOldNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetOldNamespaceName()).compareTo(other.isSetOldNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -114155,7 +114963,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNewNamespaceName()).compareTo(other.isSetNewNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNewNamespaceName()).compareTo(other.isSetNewNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -114173,16 +114981,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("renameNamespace_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("renameNamespace_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -114225,7 +115033,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -114233,13 +115041,13 @@
       }
     }
 
-    private static class renameNamespace_argsStandardSchemeFactory implements SchemeFactory {
+    private static class renameNamespace_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public renameNamespace_argsStandardScheme getScheme() {
         return new renameNamespace_argsStandardScheme();
       }
     }
 
-    private static class renameNamespace_argsStandardScheme extends StandardScheme<renameNamespace_args> {
+    private static class renameNamespace_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -114311,18 +115119,18 @@
 
     }
 
-    private static class renameNamespace_argsTupleSchemeFactory implements SchemeFactory {
+    private static class renameNamespace_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public renameNamespace_argsTupleScheme getScheme() {
         return new renameNamespace_argsTupleScheme();
       }
     }
 
-    private static class renameNamespace_argsTupleScheme extends TupleScheme<renameNamespace_args> {
+    private static class renameNamespace_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -114346,8 +115154,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -114363,6 +115171,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class renameNamespace_result implements org.apache.thrift.TBase<renameNamespace_result, renameNamespace_result._Fields>, java.io.Serializable, Cloneable, Comparable<renameNamespace_result>   {
@@ -114373,11 +115184,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new renameNamespace_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new renameNamespace_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -114391,10 +115199,10 @@
       OUCH3((short)3, "ouch3"),
       OUCH4((short)4, "ouch4");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -114423,21 +115231,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -114446,24 +115254,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceExistsException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(renameNamespace_result.class, metaDataMap);
     }
 
@@ -114609,7 +115417,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -114646,7 +115454,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -114661,13 +115469,13 @@
         return getOuch4();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -114680,11 +115488,11 @@
       case OUCH4:
         return isSetOuch4();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof renameNamespace_result)
@@ -114695,6 +115503,8 @@
     public boolean equals(renameNamespace_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -114737,29 +115547,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      boolean present_ouch4 = true && (isSetOuch4());
-      list.add(present_ouch4);
-      if (present_ouch4)
-        list.add(ouch4);
+      hashCode = hashCode * 8191 + ((isSetOuch4()) ? 131071 : 524287);
+      if (isSetOuch4())
+        hashCode = hashCode * 8191 + ouch4.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -114770,7 +115576,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -114780,7 +115586,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -114790,7 +115596,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -114800,7 +115606,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch4()).compareTo(other.isSetOuch4());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -114818,16 +115624,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("renameNamespace_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("renameNamespace_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -114878,7 +115684,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -114886,13 +115692,13 @@
       }
     }
 
-    private static class renameNamespace_resultStandardSchemeFactory implements SchemeFactory {
+    private static class renameNamespace_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public renameNamespace_resultStandardScheme getScheme() {
         return new renameNamespace_resultStandardScheme();
       }
     }
 
-    private static class renameNamespace_resultStandardScheme extends StandardScheme<renameNamespace_result> {
+    private static class renameNamespace_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -114981,18 +115787,18 @@
 
     }
 
-    private static class renameNamespace_resultTupleSchemeFactory implements SchemeFactory {
+    private static class renameNamespace_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public renameNamespace_resultTupleScheme getScheme() {
         return new renameNamespace_resultTupleScheme();
       }
     }
 
-    private static class renameNamespace_resultTupleScheme extends TupleScheme<renameNamespace_result> {
+    private static class renameNamespace_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -115022,8 +115828,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -115047,6 +115853,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class setNamespaceProperty_args implements org.apache.thrift.TBase<setNamespaceProperty_args, setNamespaceProperty_args._Fields>, java.io.Serializable, Cloneable, Comparable<setNamespaceProperty_args>   {
@@ -115057,16 +115866,13 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new setNamespaceProperty_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new setNamespaceProperty_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
-    public String property; // required
-    public String value; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String namespaceName; // required
+    public java.lang.String property; // required
+    public java.lang.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 {
@@ -115075,10 +115881,10 @@
       PROPERTY((short)3, "property"),
       VALUE((short)4, "value");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -115107,21 +115913,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -115130,15 +115936,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -115147,7 +115953,7 @@
           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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setNamespaceProperty_args.class, metaDataMap);
     }
 
@@ -115155,10 +115961,10 @@
     }
 
     public setNamespaceProperty_args(
-      ByteBuffer login,
-      String namespaceName,
-      String property,
-      String value)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName,
+      java.lang.String property,
+      java.lang.String value)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -115202,16 +116008,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public setNamespaceProperty_args setLogin(ByteBuffer login) {
+    public setNamespaceProperty_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -115231,11 +116037,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public setNamespaceProperty_args setNamespaceName(String namespaceName) {
+    public setNamespaceProperty_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -115255,11 +116061,11 @@
       }
     }
 
-    public String getProperty() {
+    public java.lang.String getProperty() {
       return this.property;
     }
 
-    public setNamespaceProperty_args setProperty(String property) {
+    public setNamespaceProperty_args setProperty(java.lang.String property) {
       this.property = property;
       return this;
     }
@@ -115279,11 +116085,11 @@
       }
     }
 
-    public String getValue() {
+    public java.lang.String getValue() {
       return this.value;
     }
 
-    public setNamespaceProperty_args setValue(String value) {
+    public setNamespaceProperty_args setValue(java.lang.String value) {
       this.value = value;
       return this;
     }
@@ -115303,13 +116109,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -115317,7 +116127,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -115325,7 +116135,7 @@
         if (value == null) {
           unsetProperty();
         } else {
-          setProperty((String)value);
+          setProperty((java.lang.String)value);
         }
         break;
 
@@ -115333,14 +116143,14 @@
         if (value == null) {
           unsetValue();
         } else {
-          setValue((String)value);
+          setValue((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -115355,13 +116165,13 @@
         return getValue();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -115374,11 +116184,11 @@
       case VALUE:
         return isSetValue();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof setNamespaceProperty_args)
@@ -115389,6 +116199,8 @@
     public boolean equals(setNamespaceProperty_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -115431,29 +116243,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_property = true && (isSetProperty());
-      list.add(present_property);
-      if (present_property)
-        list.add(property);
+      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
+      if (isSetProperty())
+        hashCode = hashCode * 8191 + property.hashCode();
 
-      boolean present_value = true && (isSetValue());
-      list.add(present_value);
-      if (present_value)
-        list.add(value);
+      hashCode = hashCode * 8191 + ((isSetValue()) ? 131071 : 524287);
+      if (isSetValue())
+        hashCode = hashCode * 8191 + value.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -115464,7 +116272,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -115474,7 +116282,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -115484,7 +116292,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
+      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -115494,7 +116302,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
+      lastComparison = java.lang.Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -115512,16 +116320,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("setNamespaceProperty_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("setNamespaceProperty_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -115572,7 +116380,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -115580,13 +116388,13 @@
       }
     }
 
-    private static class setNamespaceProperty_argsStandardSchemeFactory implements SchemeFactory {
+    private static class setNamespaceProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setNamespaceProperty_argsStandardScheme getScheme() {
         return new setNamespaceProperty_argsStandardScheme();
       }
     }
 
-    private static class setNamespaceProperty_argsStandardScheme extends StandardScheme<setNamespaceProperty_args> {
+    private static class setNamespaceProperty_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -115671,18 +116479,18 @@
 
     }
 
-    private static class setNamespaceProperty_argsTupleSchemeFactory implements SchemeFactory {
+    private static class setNamespaceProperty_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setNamespaceProperty_argsTupleScheme getScheme() {
         return new setNamespaceProperty_argsTupleScheme();
       }
     }
 
-    private static class setNamespaceProperty_argsTupleScheme extends TupleScheme<setNamespaceProperty_args> {
+    private static class setNamespaceProperty_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -115712,8 +116520,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -115733,6 +116541,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class setNamespaceProperty_result implements org.apache.thrift.TBase<setNamespaceProperty_result, setNamespaceProperty_result._Fields>, java.io.Serializable, Cloneable, Comparable<setNamespaceProperty_result>   {
@@ -115742,11 +116553,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new setNamespaceProperty_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new setNamespaceProperty_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -115758,10 +116566,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -115788,21 +116596,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -115811,22 +116619,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(setNamespaceProperty_result.class, metaDataMap);
     }
 
@@ -115942,7 +116750,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -115971,7 +116779,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -115983,13 +116791,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -116000,11 +116808,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof setNamespaceProperty_result)
@@ -116015,6 +116823,8 @@
     public boolean equals(setNamespaceProperty_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -116048,24 +116858,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -116076,7 +116883,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -116086,7 +116893,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -116096,7 +116903,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -116114,16 +116921,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("setNamespaceProperty_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("setNamespaceProperty_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -116166,7 +116973,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -116174,13 +116981,13 @@
       }
     }
 
-    private static class setNamespaceProperty_resultStandardSchemeFactory implements SchemeFactory {
+    private static class setNamespaceProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setNamespaceProperty_resultStandardScheme getScheme() {
         return new setNamespaceProperty_resultStandardScheme();
       }
     }
 
-    private static class setNamespaceProperty_resultStandardScheme extends StandardScheme<setNamespaceProperty_result> {
+    private static class setNamespaceProperty_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -116255,18 +117062,18 @@
 
     }
 
-    private static class setNamespaceProperty_resultTupleSchemeFactory implements SchemeFactory {
+    private static class setNamespaceProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public setNamespaceProperty_resultTupleScheme getScheme() {
         return new setNamespaceProperty_resultTupleScheme();
       }
     }
 
-    private static class setNamespaceProperty_resultTupleScheme extends TupleScheme<setNamespaceProperty_result> {
+    private static class setNamespaceProperty_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -116290,8 +117097,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -116310,6 +117117,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeNamespaceProperty_args implements org.apache.thrift.TBase<removeNamespaceProperty_args, removeNamespaceProperty_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceProperty_args>   {
@@ -116319,15 +117129,12 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeNamespaceProperty_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeNamespaceProperty_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
-    public String property; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String namespaceName; // required
+    public java.lang.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 {
@@ -116335,10 +117142,10 @@
       NAMESPACE_NAME((short)2, "namespaceName"),
       PROPERTY((short)3, "property");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -116365,21 +117172,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -116388,22 +117195,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceProperty_args.class, metaDataMap);
     }
 
@@ -116411,9 +117218,9 @@
     }
 
     public removeNamespaceProperty_args(
-      ByteBuffer login,
-      String namespaceName,
-      String property)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName,
+      java.lang.String property)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -116452,16 +117259,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public removeNamespaceProperty_args setLogin(ByteBuffer login) {
+    public removeNamespaceProperty_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -116481,11 +117288,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public removeNamespaceProperty_args setNamespaceName(String namespaceName) {
+    public removeNamespaceProperty_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -116505,11 +117312,11 @@
       }
     }
 
-    public String getProperty() {
+    public java.lang.String getProperty() {
       return this.property;
     }
 
-    public removeNamespaceProperty_args setProperty(String property) {
+    public removeNamespaceProperty_args setProperty(java.lang.String property) {
       this.property = property;
       return this;
     }
@@ -116529,13 +117336,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -116543,7 +117354,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -116551,14 +117362,14 @@
         if (value == null) {
           unsetProperty();
         } else {
-          setProperty((String)value);
+          setProperty((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -116570,13 +117381,13 @@
         return getProperty();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -116587,11 +117398,11 @@
       case PROPERTY:
         return isSetProperty();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeNamespaceProperty_args)
@@ -116602,6 +117413,8 @@
     public boolean equals(removeNamespaceProperty_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -116635,24 +117448,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_property = true && (isSetProperty());
-      list.add(present_property);
-      if (present_property)
-        list.add(property);
+      hashCode = hashCode * 8191 + ((isSetProperty()) ? 131071 : 524287);
+      if (isSetProperty())
+        hashCode = hashCode * 8191 + property.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -116663,7 +117473,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -116673,7 +117483,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -116683,7 +117493,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
+      lastComparison = java.lang.Boolean.valueOf(isSetProperty()).compareTo(other.isSetProperty());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -116701,16 +117511,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeNamespaceProperty_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceProperty_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -116753,7 +117563,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -116761,13 +117571,13 @@
       }
     }
 
-    private static class removeNamespaceProperty_argsStandardSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceProperty_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceProperty_argsStandardScheme getScheme() {
         return new removeNamespaceProperty_argsStandardScheme();
       }
     }
 
-    private static class removeNamespaceProperty_argsStandardScheme extends StandardScheme<removeNamespaceProperty_args> {
+    private static class removeNamespaceProperty_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -116839,18 +117649,18 @@
 
     }
 
-    private static class removeNamespaceProperty_argsTupleSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceProperty_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceProperty_argsTupleScheme getScheme() {
         return new removeNamespaceProperty_argsTupleScheme();
       }
     }
 
-    private static class removeNamespaceProperty_argsTupleScheme extends TupleScheme<removeNamespaceProperty_args> {
+    private static class removeNamespaceProperty_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -116874,8 +117684,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -116891,6 +117701,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeNamespaceProperty_result implements org.apache.thrift.TBase<removeNamespaceProperty_result, removeNamespaceProperty_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceProperty_result>   {
@@ -116900,11 +117713,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeNamespaceProperty_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeNamespaceProperty_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -116916,10 +117726,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -116946,21 +117756,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -116969,22 +117779,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceProperty_result.class, metaDataMap);
     }
 
@@ -117100,7 +117910,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -117129,7 +117939,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -117141,13 +117951,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -117158,11 +117968,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeNamespaceProperty_result)
@@ -117173,6 +117983,8 @@
     public boolean equals(removeNamespaceProperty_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -117206,24 +118018,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -117234,7 +118043,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -117244,7 +118053,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -117254,7 +118063,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -117272,16 +118081,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeNamespaceProperty_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceProperty_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -117324,7 +118133,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -117332,13 +118141,13 @@
       }
     }
 
-    private static class removeNamespaceProperty_resultStandardSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceProperty_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceProperty_resultStandardScheme getScheme() {
         return new removeNamespaceProperty_resultStandardScheme();
       }
     }
 
-    private static class removeNamespaceProperty_resultStandardScheme extends StandardScheme<removeNamespaceProperty_result> {
+    private static class removeNamespaceProperty_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -117413,18 +118222,18 @@
 
     }
 
-    private static class removeNamespaceProperty_resultTupleSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceProperty_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceProperty_resultTupleScheme getScheme() {
         return new removeNamespaceProperty_resultTupleScheme();
       }
     }
 
-    private static class removeNamespaceProperty_resultTupleScheme extends TupleScheme<removeNamespaceProperty_result> {
+    private static class removeNamespaceProperty_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -117448,8 +118257,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -117468,6 +118277,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getNamespaceProperties_args implements org.apache.thrift.TBase<getNamespaceProperties_args, getNamespaceProperties_args._Fields>, java.io.Serializable, Cloneable, Comparable<getNamespaceProperties_args>   {
@@ -117476,24 +118288,21 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getNamespaceProperties_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getNamespaceProperties_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -117518,21 +118327,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -117541,20 +118350,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getNamespaceProperties_args.class, metaDataMap);
     }
 
@@ -117562,8 +118371,8 @@
     }
 
     public getNamespaceProperties_args(
-      ByteBuffer login,
-      String namespaceName)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -117597,16 +118406,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getNamespaceProperties_args setLogin(ByteBuffer login) {
+    public getNamespaceProperties_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -117626,11 +118435,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public getNamespaceProperties_args setNamespaceName(String namespaceName) {
+    public getNamespaceProperties_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -117650,13 +118459,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -117664,14 +118477,14 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -117680,13 +118493,13 @@
         return getNamespaceName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -117695,11 +118508,11 @@
       case NAMESPACE_NAME:
         return isSetNamespaceName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getNamespaceProperties_args)
@@ -117710,6 +118523,8 @@
     public boolean equals(getNamespaceProperties_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -117734,19 +118549,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -117757,7 +118570,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -117767,7 +118580,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -117785,16 +118598,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getNamespaceProperties_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getNamespaceProperties_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -117829,7 +118642,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -117837,13 +118650,13 @@
       }
     }
 
-    private static class getNamespaceProperties_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getNamespaceProperties_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getNamespaceProperties_argsStandardScheme getScheme() {
         return new getNamespaceProperties_argsStandardScheme();
       }
     }
 
-    private static class getNamespaceProperties_argsStandardScheme extends StandardScheme<getNamespaceProperties_args> {
+    private static class getNamespaceProperties_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -117902,18 +118715,18 @@
 
     }
 
-    private static class getNamespaceProperties_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getNamespaceProperties_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getNamespaceProperties_argsTupleScheme getScheme() {
         return new getNamespaceProperties_argsTupleScheme();
       }
     }
 
-    private static class getNamespaceProperties_argsTupleScheme extends TupleScheme<getNamespaceProperties_args> {
+    private static class getNamespaceProperties_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -117931,8 +118744,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -117944,6 +118757,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getNamespaceProperties_result implements org.apache.thrift.TBase<getNamespaceProperties_result, getNamespaceProperties_result._Fields>, java.io.Serializable, Cloneable, Comparable<getNamespaceProperties_result>   {
@@ -117954,13 +118770,10 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getNamespaceProperties_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getNamespaceProperties_resultTupleSchemeFactory();
 
-    public Map<String,String> success; // required
+    public java.util.Map<java.lang.String,java.lang.String> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public NamespaceNotFoundException ouch3; // required
@@ -117972,10 +118785,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -118004,21 +118817,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -118027,26 +118840,26 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getNamespaceProperties_result.class, metaDataMap);
     }
 
@@ -118054,7 +118867,7 @@
     }
 
     public getNamespaceProperties_result(
-      Map<String,String> success,
+      java.util.Map<java.lang.String,java.lang.String> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       NamespaceNotFoundException ouch3)
@@ -118071,7 +118884,7 @@
      */
     public getNamespaceProperties_result(getNamespaceProperties_result other) {
       if (other.isSetSuccess()) {
-        Map<String,String> __this__success = new HashMap<String,String>(other.success);
+        java.util.Map<java.lang.String,java.lang.String> __this__success = new java.util.HashMap<java.lang.String,java.lang.String>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -118101,18 +118914,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, String val) {
+    public void putToSuccess(java.lang.String key, java.lang.String val) {
       if (this.success == null) {
-        this.success = new HashMap<String,String>();
+        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,String> getSuccess() {
+    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
       return this.success;
     }
 
-    public getNamespaceProperties_result setSuccess(Map<String,String> success) {
+    public getNamespaceProperties_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
       this.success = success;
       return this;
     }
@@ -118204,13 +119017,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,String>)value);
+          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
         }
         break;
 
@@ -118241,7 +119054,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -118256,13 +119069,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -118275,11 +119088,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getNamespaceProperties_result)
@@ -118290,6 +119103,8 @@
     public boolean equals(getNamespaceProperties_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -118332,29 +119147,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -118365,7 +119176,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -118375,7 +119186,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -118385,7 +119196,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -118395,7 +119206,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -118413,16 +119224,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getNamespaceProperties_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getNamespaceProperties_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -118473,7 +119284,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -118481,13 +119292,13 @@
       }
     }
 
-    private static class getNamespaceProperties_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getNamespaceProperties_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getNamespaceProperties_resultStandardScheme getScheme() {
         return new getNamespaceProperties_resultStandardScheme();
       }
     }
 
-    private static class getNamespaceProperties_resultStandardScheme extends StandardScheme<getNamespaceProperties_result> {
+    private static class getNamespaceProperties_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -118503,9 +119314,9 @@
               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;
+                  struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map506.size);
+                  java.lang.String _key507;
+                  java.lang.String _val508;
                   for (int _i509 = 0; _i509 < _map506.size; ++_i509)
                   {
                     _key507 = iprot.readString();
@@ -118565,7 +119376,7 @@
           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())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter510 : struct.success.entrySet())
             {
               oprot.writeString(_iter510.getKey());
               oprot.writeString(_iter510.getValue());
@@ -118595,18 +119406,18 @@
 
     }
 
-    private static class getNamespaceProperties_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getNamespaceProperties_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getNamespaceProperties_resultTupleScheme getScheme() {
         return new getNamespaceProperties_resultTupleScheme();
       }
     }
 
-    private static class getNamespaceProperties_resultTupleScheme extends TupleScheme<getNamespaceProperties_result> {
+    private static class getNamespaceProperties_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -118623,7 +119434,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, String> _iter511 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter511 : struct.success.entrySet())
             {
               oprot.writeString(_iter511.getKey());
               oprot.writeString(_iter511.getValue());
@@ -118643,14 +119454,14 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.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;
+            struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map512.size);
+            java.lang.String _key513;
+            java.lang.String _val514;
             for (int _i515 = 0; _i515 < _map512.size; ++_i515)
             {
               _key513 = iprot.readString();
@@ -118678,6 +119489,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class namespaceIdMap_args implements org.apache.thrift.TBase<namespaceIdMap_args, namespaceIdMap_args._Fields>, java.io.Serializable, Cloneable, Comparable<namespaceIdMap_args>   {
@@ -118685,22 +119499,19 @@
 
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new namespaceIdMap_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new namespaceIdMap_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
+    public java.nio.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -118723,21 +119534,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -118746,18 +119557,18 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(namespaceIdMap_args.class, metaDataMap);
     }
 
@@ -118765,7 +119576,7 @@
     }
 
     public namespaceIdMap_args(
-      ByteBuffer login)
+      java.nio.ByteBuffer login)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -118794,16 +119605,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public namespaceIdMap_args setLogin(ByteBuffer login) {
+    public namespaceIdMap_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -118823,43 +119634,47 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
       case LOGIN:
         return isSetLogin();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof namespaceIdMap_args)
@@ -118870,6 +119685,8 @@
     public boolean equals(namespaceIdMap_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -118885,14 +119702,13 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -118903,7 +119719,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -118921,16 +119737,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("namespaceIdMap_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("namespaceIdMap_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -118957,7 +119773,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -118965,13 +119781,13 @@
       }
     }
 
-    private static class namespaceIdMap_argsStandardSchemeFactory implements SchemeFactory {
+    private static class namespaceIdMap_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public namespaceIdMap_argsStandardScheme getScheme() {
         return new namespaceIdMap_argsStandardScheme();
       }
     }
 
-    private static class namespaceIdMap_argsStandardScheme extends StandardScheme<namespaceIdMap_args> {
+    private static class namespaceIdMap_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -119017,18 +119833,18 @@
 
     }
 
-    private static class namespaceIdMap_argsTupleSchemeFactory implements SchemeFactory {
+    private static class namespaceIdMap_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public namespaceIdMap_argsTupleScheme getScheme() {
         return new namespaceIdMap_argsTupleScheme();
       }
     }
 
-    private static class namespaceIdMap_argsTupleScheme extends TupleScheme<namespaceIdMap_args> {
+    private static class namespaceIdMap_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -119040,8 +119856,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -119049,6 +119865,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class namespaceIdMap_result implements org.apache.thrift.TBase<namespaceIdMap_result, namespaceIdMap_result._Fields>, java.io.Serializable, Cloneable, Comparable<namespaceIdMap_result>   {
@@ -119058,13 +119877,10 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new namespaceIdMap_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new namespaceIdMap_resultTupleSchemeFactory();
 
-    public Map<String,String> success; // required
+    public java.util.Map<java.lang.String,java.lang.String> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
 
@@ -119074,10 +119890,10 @@
       OUCH1((short)1, "ouch1"),
       OUCH2((short)2, "ouch2");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -119104,21 +119920,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -119127,24 +119943,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(namespaceIdMap_result.class, metaDataMap);
     }
 
@@ -119152,7 +119968,7 @@
     }
 
     public namespaceIdMap_result(
-      Map<String,String> success,
+      java.util.Map<java.lang.String,java.lang.String> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2)
     {
@@ -119167,7 +119983,7 @@
      */
     public namespaceIdMap_result(namespaceIdMap_result other) {
       if (other.isSetSuccess()) {
-        Map<String,String> __this__success = new HashMap<String,String>(other.success);
+        java.util.Map<java.lang.String,java.lang.String> __this__success = new java.util.HashMap<java.lang.String,java.lang.String>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -119193,18 +120009,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, String val) {
+    public void putToSuccess(java.lang.String key, java.lang.String val) {
       if (this.success == null) {
-        this.success = new HashMap<String,String>();
+        this.success = new java.util.HashMap<java.lang.String,java.lang.String>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,String> getSuccess() {
+    public java.util.Map<java.lang.String,java.lang.String> getSuccess() {
       return this.success;
     }
 
-    public namespaceIdMap_result setSuccess(Map<String,String> success) {
+    public namespaceIdMap_result setSuccess(java.util.Map<java.lang.String,java.lang.String> success) {
       this.success = success;
       return this;
     }
@@ -119272,13 +120088,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,String>)value);
+          setSuccess((java.util.Map<java.lang.String,java.lang.String>)value);
         }
         break;
 
@@ -119301,7 +120117,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -119313,13 +120129,13 @@
         return getOuch2();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -119330,11 +120146,11 @@
       case OUCH2:
         return isSetOuch2();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof namespaceIdMap_result)
@@ -119345,6 +120161,8 @@
     public boolean equals(namespaceIdMap_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -119378,24 +120196,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -119406,7 +120221,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -119416,7 +120231,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -119426,7 +120241,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -119444,16 +120259,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("namespaceIdMap_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("namespaceIdMap_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -119496,7 +120311,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -119504,13 +120319,13 @@
       }
     }
 
-    private static class namespaceIdMap_resultStandardSchemeFactory implements SchemeFactory {
+    private static class namespaceIdMap_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public namespaceIdMap_resultStandardScheme getScheme() {
         return new namespaceIdMap_resultStandardScheme();
       }
     }
 
-    private static class namespaceIdMap_resultStandardScheme extends StandardScheme<namespaceIdMap_result> {
+    private static class namespaceIdMap_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -119526,9 +120341,9 @@
               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;
+                  struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map516.size);
+                  java.lang.String _key517;
+                  java.lang.String _val518;
                   for (int _i519 = 0; _i519 < _map516.size; ++_i519)
                   {
                     _key517 = iprot.readString();
@@ -119579,7 +120394,7 @@
           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())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter520 : struct.success.entrySet())
             {
               oprot.writeString(_iter520.getKey());
               oprot.writeString(_iter520.getValue());
@@ -119604,18 +120419,18 @@
 
     }
 
-    private static class namespaceIdMap_resultTupleSchemeFactory implements SchemeFactory {
+    private static class namespaceIdMap_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public namespaceIdMap_resultTupleScheme getScheme() {
         return new namespaceIdMap_resultTupleScheme();
       }
     }
 
-    private static class namespaceIdMap_resultTupleScheme extends TupleScheme<namespaceIdMap_result> {
+    private static class namespaceIdMap_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -119629,7 +120444,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, String> _iter521 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter521 : struct.success.entrySet())
             {
               oprot.writeString(_iter521.getKey());
               oprot.writeString(_iter521.getValue());
@@ -119646,14 +120461,14 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.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;
+            struct.success = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map522.size);
+            java.lang.String _key523;
+            java.lang.String _val524;
             for (int _i525 = 0; _i525 < _map522.size; ++_i525)
             {
               _key523 = iprot.readString();
@@ -119676,6 +120491,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class attachNamespaceIterator_args implements org.apache.thrift.TBase<attachNamespaceIterator_args, attachNamespaceIterator_args._Fields>, java.io.Serializable, Cloneable, Comparable<attachNamespaceIterator_args>   {
@@ -119686,16 +120504,13 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new attachNamespaceIterator_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new attachNamespaceIterator_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String namespaceName; // required
     public IteratorSetting setting; // required
-    public Set<IteratorScope> scopes; // required
+    public java.util.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 {
@@ -119704,10 +120519,10 @@
       SETTING((short)3, "setting"),
       SCOPES((short)4, "scopes");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -119736,21 +120551,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -119759,15 +120574,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -119777,7 +120592,7 @@
       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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(attachNamespaceIterator_args.class, metaDataMap);
     }
 
@@ -119785,10 +120600,10 @@
     }
 
     public attachNamespaceIterator_args(
-      ByteBuffer login,
-      String namespaceName,
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName,
       IteratorSetting setting,
-      Set<IteratorScope> scopes)
+      java.util.Set<IteratorScope> scopes)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -119811,7 +120626,7 @@
         this.setting = new IteratorSetting(other.setting);
       }
       if (other.isSetScopes()) {
-        Set<IteratorScope> __this__scopes = new HashSet<IteratorScope>(other.scopes.size());
+        java.util.Set<IteratorScope> __this__scopes = new java.util.HashSet<IteratorScope>(other.scopes.size());
         for (IteratorScope other_element : other.scopes) {
           __this__scopes.add(other_element);
         }
@@ -119836,16 +120651,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public attachNamespaceIterator_args setLogin(ByteBuffer login) {
+    public attachNamespaceIterator_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -119865,11 +120680,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public attachNamespaceIterator_args setNamespaceName(String namespaceName) {
+    public attachNamespaceIterator_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -119923,16 +120738,16 @@
 
     public void addToScopes(IteratorScope elem) {
       if (this.scopes == null) {
-        this.scopes = new HashSet<IteratorScope>();
+        this.scopes = new java.util.HashSet<IteratorScope>();
       }
       this.scopes.add(elem);
     }
 
-    public Set<IteratorScope> getScopes() {
+    public java.util.Set<IteratorScope> getScopes() {
       return this.scopes;
     }
 
-    public attachNamespaceIterator_args setScopes(Set<IteratorScope> scopes) {
+    public attachNamespaceIterator_args setScopes(java.util.Set<IteratorScope> scopes) {
       this.scopes = scopes;
       return this;
     }
@@ -119952,13 +120767,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -119966,7 +120785,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -119982,14 +120801,14 @@
         if (value == null) {
           unsetScopes();
         } else {
-          setScopes((Set<IteratorScope>)value);
+          setScopes((java.util.Set<IteratorScope>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -120004,13 +120823,13 @@
         return getScopes();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -120023,11 +120842,11 @@
       case SCOPES:
         return isSetScopes();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof attachNamespaceIterator_args)
@@ -120038,6 +120857,8 @@
     public boolean equals(attachNamespaceIterator_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -120080,29 +120901,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_setting = true && (isSetSetting());
-      list.add(present_setting);
-      if (present_setting)
-        list.add(setting);
+      hashCode = hashCode * 8191 + ((isSetSetting()) ? 131071 : 524287);
+      if (isSetSetting())
+        hashCode = hashCode * 8191 + setting.hashCode();
 
-      boolean present_scopes = true && (isSetScopes());
-      list.add(present_scopes);
-      if (present_scopes)
-        list.add(scopes);
+      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
+      if (isSetScopes())
+        hashCode = hashCode * 8191 + scopes.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -120113,7 +120930,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -120123,7 +120940,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -120133,7 +120950,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
+      lastComparison = java.lang.Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -120143,7 +120960,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
+      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -120161,16 +120978,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("attachNamespaceIterator_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("attachNamespaceIterator_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -120224,7 +121041,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -120232,13 +121049,13 @@
       }
     }
 
-    private static class attachNamespaceIterator_argsStandardSchemeFactory implements SchemeFactory {
+    private static class attachNamespaceIterator_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public attachNamespaceIterator_argsStandardScheme getScheme() {
         return new attachNamespaceIterator_argsStandardScheme();
       }
     }
 
-    private static class attachNamespaceIterator_argsStandardScheme extends StandardScheme<attachNamespaceIterator_args> {
+    private static class attachNamespaceIterator_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -120279,7 +121096,7 @@
               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);
+                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set526.size);
                   IteratorScope _elem527;
                   for (int _i528 = 0; _i528 < _set526.size; ++_i528)
                   {
@@ -120341,18 +121158,18 @@
 
     }
 
-    private static class attachNamespaceIterator_argsTupleSchemeFactory implements SchemeFactory {
+    private static class attachNamespaceIterator_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public attachNamespaceIterator_argsTupleScheme getScheme() {
         return new attachNamespaceIterator_argsTupleScheme();
       }
     }
 
-    private static class attachNamespaceIterator_argsTupleScheme extends TupleScheme<attachNamespaceIterator_args> {
+    private static class attachNamespaceIterator_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -120388,8 +121205,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -120406,7 +121223,7 @@
         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);
+            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set531.size);
             IteratorScope _elem532;
             for (int _i533 = 0; _i533 < _set531.size; ++_i533)
             {
@@ -120419,6 +121236,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class attachNamespaceIterator_result implements org.apache.thrift.TBase<attachNamespaceIterator_result, attachNamespaceIterator_result._Fields>, java.io.Serializable, Cloneable, Comparable<attachNamespaceIterator_result>   {
@@ -120428,11 +121248,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new attachNamespaceIterator_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new attachNamespaceIterator_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -120444,10 +121261,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -120474,21 +121291,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -120497,22 +121314,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(attachNamespaceIterator_result.class, metaDataMap);
     }
 
@@ -120628,7 +121445,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -120657,7 +121474,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -120669,13 +121486,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -120686,11 +121503,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof attachNamespaceIterator_result)
@@ -120701,6 +121518,8 @@
     public boolean equals(attachNamespaceIterator_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -120734,24 +121553,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -120762,7 +121578,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -120772,7 +121588,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -120782,7 +121598,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -120800,16 +121616,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("attachNamespaceIterator_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("attachNamespaceIterator_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -120852,7 +121668,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -120860,13 +121676,13 @@
       }
     }
 
-    private static class attachNamespaceIterator_resultStandardSchemeFactory implements SchemeFactory {
+    private static class attachNamespaceIterator_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public attachNamespaceIterator_resultStandardScheme getScheme() {
         return new attachNamespaceIterator_resultStandardScheme();
       }
     }
 
-    private static class attachNamespaceIterator_resultStandardScheme extends StandardScheme<attachNamespaceIterator_result> {
+    private static class attachNamespaceIterator_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -120941,18 +121757,18 @@
 
     }
 
-    private static class attachNamespaceIterator_resultTupleSchemeFactory implements SchemeFactory {
+    private static class attachNamespaceIterator_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public attachNamespaceIterator_resultTupleScheme getScheme() {
         return new attachNamespaceIterator_resultTupleScheme();
       }
     }
 
-    private static class attachNamespaceIterator_resultTupleScheme extends TupleScheme<attachNamespaceIterator_result> {
+    private static class attachNamespaceIterator_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -120976,8 +121792,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -120996,6 +121812,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeNamespaceIterator_args implements org.apache.thrift.TBase<removeNamespaceIterator_args, removeNamespaceIterator_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceIterator_args>   {
@@ -121006,16 +121825,13 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeNamespaceIterator_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeNamespaceIterator_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
-    public String name; // required
-    public Set<IteratorScope> scopes; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String namespaceName; // required
+    public java.lang.String name; // required
+    public java.util.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 {
@@ -121024,10 +121840,10 @@
       NAME((short)3, "name"),
       SCOPES((short)4, "scopes");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -121056,21 +121872,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -121079,15 +121895,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -121097,7 +121913,7 @@
       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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceIterator_args.class, metaDataMap);
     }
 
@@ -121105,10 +121921,10 @@
     }
 
     public removeNamespaceIterator_args(
-      ByteBuffer login,
-      String namespaceName,
-      String name,
-      Set<IteratorScope> scopes)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName,
+      java.lang.String name,
+      java.util.Set<IteratorScope> scopes)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -121131,7 +121947,7 @@
         this.name = other.name;
       }
       if (other.isSetScopes()) {
-        Set<IteratorScope> __this__scopes = new HashSet<IteratorScope>(other.scopes.size());
+        java.util.Set<IteratorScope> __this__scopes = new java.util.HashSet<IteratorScope>(other.scopes.size());
         for (IteratorScope other_element : other.scopes) {
           __this__scopes.add(other_element);
         }
@@ -121156,16 +121972,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public removeNamespaceIterator_args setLogin(ByteBuffer login) {
+    public removeNamespaceIterator_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -121185,11 +122001,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public removeNamespaceIterator_args setNamespaceName(String namespaceName) {
+    public removeNamespaceIterator_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -121209,11 +122025,11 @@
       }
     }
 
-    public String getName() {
+    public java.lang.String getName() {
       return this.name;
     }
 
-    public removeNamespaceIterator_args setName(String name) {
+    public removeNamespaceIterator_args setName(java.lang.String name) {
       this.name = name;
       return this;
     }
@@ -121243,16 +122059,16 @@
 
     public void addToScopes(IteratorScope elem) {
       if (this.scopes == null) {
-        this.scopes = new HashSet<IteratorScope>();
+        this.scopes = new java.util.HashSet<IteratorScope>();
       }
       this.scopes.add(elem);
     }
 
-    public Set<IteratorScope> getScopes() {
+    public java.util.Set<IteratorScope> getScopes() {
       return this.scopes;
     }
 
-    public removeNamespaceIterator_args setScopes(Set<IteratorScope> scopes) {
+    public removeNamespaceIterator_args setScopes(java.util.Set<IteratorScope> scopes) {
       this.scopes = scopes;
       return this;
     }
@@ -121272,13 +122088,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -121286,7 +122106,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -121294,7 +122114,7 @@
         if (value == null) {
           unsetName();
         } else {
-          setName((String)value);
+          setName((java.lang.String)value);
         }
         break;
 
@@ -121302,14 +122122,14 @@
         if (value == null) {
           unsetScopes();
         } else {
-          setScopes((Set<IteratorScope>)value);
+          setScopes((java.util.Set<IteratorScope>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -121324,13 +122144,13 @@
         return getScopes();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -121343,11 +122163,11 @@
       case SCOPES:
         return isSetScopes();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeNamespaceIterator_args)
@@ -121358,6 +122178,8 @@
     public boolean equals(removeNamespaceIterator_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -121400,29 +122222,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_name = true && (isSetName());
-      list.add(present_name);
-      if (present_name)
-        list.add(name);
+      hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287);
+      if (isSetName())
+        hashCode = hashCode * 8191 + name.hashCode();
 
-      boolean present_scopes = true && (isSetScopes());
-      list.add(present_scopes);
-      if (present_scopes)
-        list.add(scopes);
+      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
+      if (isSetScopes())
+        hashCode = hashCode * 8191 + scopes.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -121433,7 +122251,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -121443,7 +122261,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -121453,7 +122271,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName());
+      lastComparison = java.lang.Boolean.valueOf(isSetName()).compareTo(other.isSetName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -121463,7 +122281,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
+      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -121481,16 +122299,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeNamespaceIterator_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceIterator_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -121541,7 +122359,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -121549,13 +122367,13 @@
       }
     }
 
-    private static class removeNamespaceIterator_argsStandardSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceIterator_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceIterator_argsStandardScheme getScheme() {
         return new removeNamespaceIterator_argsStandardScheme();
       }
     }
 
-    private static class removeNamespaceIterator_argsStandardScheme extends StandardScheme<removeNamespaceIterator_args> {
+    private static class removeNamespaceIterator_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -121595,7 +122413,7 @@
               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);
+                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set534.size);
                   IteratorScope _elem535;
                   for (int _i536 = 0; _i536 < _set534.size; ++_i536)
                   {
@@ -121657,18 +122475,18 @@
 
     }
 
-    private static class removeNamespaceIterator_argsTupleSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceIterator_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceIterator_argsTupleScheme getScheme() {
         return new removeNamespaceIterator_argsTupleScheme();
       }
     }
 
-    private static class removeNamespaceIterator_argsTupleScheme extends TupleScheme<removeNamespaceIterator_args> {
+    private static class removeNamespaceIterator_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -121704,8 +122522,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -121721,7 +122539,7 @@
         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);
+            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set539.size);
             IteratorScope _elem540;
             for (int _i541 = 0; _i541 < _set539.size; ++_i541)
             {
@@ -121734,6 +122552,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeNamespaceIterator_result implements org.apache.thrift.TBase<removeNamespaceIterator_result, removeNamespaceIterator_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceIterator_result>   {
@@ -121743,11 +122564,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeNamespaceIterator_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeNamespaceIterator_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -121759,10 +122577,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -121789,21 +122607,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -121812,22 +122630,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceIterator_result.class, metaDataMap);
     }
 
@@ -121943,7 +122761,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -121972,7 +122790,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -121984,13 +122802,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -122001,11 +122819,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeNamespaceIterator_result)
@@ -122016,6 +122834,8 @@
     public boolean equals(removeNamespaceIterator_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -122049,24 +122869,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -122077,7 +122894,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -122087,7 +122904,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -122097,7 +122914,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -122115,16 +122932,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeNamespaceIterator_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceIterator_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -122167,7 +122984,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -122175,13 +122992,13 @@
       }
     }
 
-    private static class removeNamespaceIterator_resultStandardSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceIterator_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceIterator_resultStandardScheme getScheme() {
         return new removeNamespaceIterator_resultStandardScheme();
       }
     }
 
-    private static class removeNamespaceIterator_resultStandardScheme extends StandardScheme<removeNamespaceIterator_result> {
+    private static class removeNamespaceIterator_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -122256,18 +123073,18 @@
 
     }
 
-    private static class removeNamespaceIterator_resultTupleSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceIterator_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceIterator_resultTupleScheme getScheme() {
         return new removeNamespaceIterator_resultTupleScheme();
       }
     }
 
-    private static class removeNamespaceIterator_resultTupleScheme extends TupleScheme<removeNamespaceIterator_result> {
+    private static class removeNamespaceIterator_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -122291,8 +123108,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -122311,6 +123128,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getNamespaceIteratorSetting_args implements org.apache.thrift.TBase<getNamespaceIteratorSetting_args, getNamespaceIteratorSetting_args._Fields>, java.io.Serializable, Cloneable, Comparable<getNamespaceIteratorSetting_args>   {
@@ -122321,15 +123141,12 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getNamespaceIteratorSetting_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getNamespaceIteratorSetting_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
-    public String name; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String namespaceName; // required
+    public java.lang.String name; // required
     /**
      * 
      * @see IteratorScope
@@ -122347,10 +123164,10 @@
        */
       SCOPE((short)4, "scope");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -122379,21 +123196,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -122402,15 +123219,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -122419,7 +123236,7 @@
           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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getNamespaceIteratorSetting_args.class, metaDataMap);
     }
 
@@ -122427,9 +123244,9 @@
     }
 
     public getNamespaceIteratorSetting_args(
-      ByteBuffer login,
-      String namespaceName,
-      String name,
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName,
+      java.lang.String name,
       IteratorScope scope)
     {
       this();
@@ -122474,16 +123291,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public getNamespaceIteratorSetting_args setLogin(ByteBuffer login) {
+    public getNamespaceIteratorSetting_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -122503,11 +123320,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public getNamespaceIteratorSetting_args setNamespaceName(String namespaceName) {
+    public getNamespaceIteratorSetting_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -122527,11 +123344,11 @@
       }
     }
 
-    public String getName() {
+    public java.lang.String getName() {
       return this.name;
     }
 
-    public getNamespaceIteratorSetting_args setName(String name) {
+    public getNamespaceIteratorSetting_args setName(java.lang.String name) {
       this.name = name;
       return this;
     }
@@ -122583,13 +123400,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -122597,7 +123418,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -122605,7 +123426,7 @@
         if (value == null) {
           unsetName();
         } else {
-          setName((String)value);
+          setName((java.lang.String)value);
         }
         break;
 
@@ -122620,7 +123441,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -122635,13 +123456,13 @@
         return getScope();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -122654,11 +123475,11 @@
       case SCOPE:
         return isSetScope();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getNamespaceIteratorSetting_args)
@@ -122669,6 +123490,8 @@
     public boolean equals(getNamespaceIteratorSetting_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -122711,29 +123534,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_name = true && (isSetName());
-      list.add(present_name);
-      if (present_name)
-        list.add(name);
+      hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287);
+      if (isSetName())
+        hashCode = hashCode * 8191 + name.hashCode();
 
-      boolean present_scope = true && (isSetScope());
-      list.add(present_scope);
-      if (present_scope)
-        list.add(scope.getValue());
+      hashCode = hashCode * 8191 + ((isSetScope()) ? 131071 : 524287);
+      if (isSetScope())
+        hashCode = hashCode * 8191 + scope.getValue();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -122744,7 +123563,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -122754,7 +123573,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -122764,7 +123583,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName());
+      lastComparison = java.lang.Boolean.valueOf(isSetName()).compareTo(other.isSetName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -122774,7 +123593,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetScope()).compareTo(other.isSetScope());
+      lastComparison = java.lang.Boolean.valueOf(isSetScope()).compareTo(other.isSetScope());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -122792,16 +123611,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getNamespaceIteratorSetting_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getNamespaceIteratorSetting_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -122852,7 +123671,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -122860,13 +123679,13 @@
       }
     }
 
-    private static class getNamespaceIteratorSetting_argsStandardSchemeFactory implements SchemeFactory {
+    private static class getNamespaceIteratorSetting_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getNamespaceIteratorSetting_argsStandardScheme getScheme() {
         return new getNamespaceIteratorSetting_argsStandardScheme();
       }
     }
 
-    private static class getNamespaceIteratorSetting_argsStandardScheme extends StandardScheme<getNamespaceIteratorSetting_args> {
+    private static class getNamespaceIteratorSetting_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -122951,18 +123770,18 @@
 
     }
 
-    private static class getNamespaceIteratorSetting_argsTupleSchemeFactory implements SchemeFactory {
+    private static class getNamespaceIteratorSetting_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getNamespaceIteratorSetting_argsTupleScheme getScheme() {
         return new getNamespaceIteratorSetting_argsTupleScheme();
       }
     }
 
-    private static class getNamespaceIteratorSetting_argsTupleScheme extends TupleScheme<getNamespaceIteratorSetting_args> {
+    private static class getNamespaceIteratorSetting_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -122992,8 +123811,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -123013,6 +123832,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class getNamespaceIteratorSetting_result implements org.apache.thrift.TBase<getNamespaceIteratorSetting_result, getNamespaceIteratorSetting_result._Fields>, java.io.Serializable, Cloneable, Comparable<getNamespaceIteratorSetting_result>   {
@@ -123023,11 +123845,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getNamespaceIteratorSetting_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getNamespaceIteratorSetting_resultTupleSchemeFactory();
 
     public IteratorSetting success; // required
     public AccumuloException ouch1; // required
@@ -123041,10 +123860,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -123073,21 +123892,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -123096,24 +123915,24 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getNamespaceIteratorSetting_result.class, metaDataMap);
     }
 
@@ -123259,7 +124078,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
@@ -123296,7 +124115,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -123311,13 +124130,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -123330,11 +124149,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof getNamespaceIteratorSetting_result)
@@ -123345,6 +124164,8 @@
     public boolean equals(getNamespaceIteratorSetting_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -123387,29 +124208,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -123420,7 +124237,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -123430,7 +124247,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -123440,7 +124257,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -123450,7 +124267,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -123468,16 +124285,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getNamespaceIteratorSetting_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("getNamespaceIteratorSetting_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -123531,7 +124348,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -123539,13 +124356,13 @@
       }
     }
 
-    private static class getNamespaceIteratorSetting_resultStandardSchemeFactory implements SchemeFactory {
+    private static class getNamespaceIteratorSetting_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getNamespaceIteratorSetting_resultStandardScheme getScheme() {
         return new getNamespaceIteratorSetting_resultStandardScheme();
       }
     }
 
-    private static class getNamespaceIteratorSetting_resultStandardScheme extends StandardScheme<getNamespaceIteratorSetting_result> {
+    private static class getNamespaceIteratorSetting_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -123634,18 +124451,18 @@
 
     }
 
-    private static class getNamespaceIteratorSetting_resultTupleSchemeFactory implements SchemeFactory {
+    private static class getNamespaceIteratorSetting_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public getNamespaceIteratorSetting_resultTupleScheme getScheme() {
         return new getNamespaceIteratorSetting_resultTupleScheme();
       }
     }
 
-    private static class getNamespaceIteratorSetting_resultTupleScheme extends TupleScheme<getNamespaceIteratorSetting_result> {
+    private static class getNamespaceIteratorSetting_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -123675,8 +124492,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = new IteratorSetting();
           struct.success.read(iprot);
@@ -123700,6 +124517,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listNamespaceIterators_args implements org.apache.thrift.TBase<listNamespaceIterators_args, listNamespaceIterators_args._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaceIterators_args>   {
@@ -123708,24 +124528,21 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listNamespaceIterators_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listNamespaceIterators_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -123750,21 +124567,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -123773,20 +124590,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaceIterators_args.class, metaDataMap);
     }
 
@@ -123794,8 +124611,8 @@
     }
 
     public listNamespaceIterators_args(
-      ByteBuffer login,
-      String namespaceName)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -123829,16 +124646,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public listNamespaceIterators_args setLogin(ByteBuffer login) {
+    public listNamespaceIterators_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -123858,11 +124675,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public listNamespaceIterators_args setNamespaceName(String namespaceName) {
+    public listNamespaceIterators_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -123882,13 +124699,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -123896,14 +124717,14 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -123912,13 +124733,13 @@
         return getNamespaceName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -123927,11 +124748,11 @@
       case NAMESPACE_NAME:
         return isSetNamespaceName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listNamespaceIterators_args)
@@ -123942,6 +124763,8 @@
     public boolean equals(listNamespaceIterators_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -123966,19 +124789,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -123989,7 +124810,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -123999,7 +124820,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -124017,16 +124838,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listNamespaceIterators_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaceIterators_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -124061,7 +124882,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -124069,13 +124890,13 @@
       }
     }
 
-    private static class listNamespaceIterators_argsStandardSchemeFactory implements SchemeFactory {
+    private static class listNamespaceIterators_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaceIterators_argsStandardScheme getScheme() {
         return new listNamespaceIterators_argsStandardScheme();
       }
     }
 
-    private static class listNamespaceIterators_argsStandardScheme extends StandardScheme<listNamespaceIterators_args> {
+    private static class listNamespaceIterators_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -124134,18 +124955,18 @@
 
     }
 
-    private static class listNamespaceIterators_argsTupleSchemeFactory implements SchemeFactory {
+    private static class listNamespaceIterators_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaceIterators_argsTupleScheme getScheme() {
         return new listNamespaceIterators_argsTupleScheme();
       }
     }
 
-    private static class listNamespaceIterators_argsTupleScheme extends TupleScheme<listNamespaceIterators_args> {
+    private static class listNamespaceIterators_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -124163,8 +124984,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -124176,6 +124997,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listNamespaceIterators_result implements org.apache.thrift.TBase<listNamespaceIterators_result, listNamespaceIterators_result._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaceIterators_result>   {
@@ -124186,13 +125010,10 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listNamespaceIterators_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listNamespaceIterators_resultTupleSchemeFactory();
 
-    public Map<String,Set<IteratorScope>> success; // required
+    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public NamespaceNotFoundException ouch3; // required
@@ -124204,10 +125025,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -124236,21 +125057,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -124259,27 +125080,27 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaceIterators_result.class, metaDataMap);
     }
 
@@ -124287,7 +125108,7 @@
     }
 
     public listNamespaceIterators_result(
-      Map<String,Set<IteratorScope>> success,
+      java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       NamespaceNotFoundException ouch3)
@@ -124304,15 +125125,15 @@
      */
     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()) {
+        java.util.Map<java.lang.String,java.util.Set<IteratorScope>> __this__success = new java.util.HashMap<java.lang.String,java.util.Set<IteratorScope>>(other.success.size());
+        for (java.util.Map.Entry<java.lang.String, java.util.Set<IteratorScope>> other_element : other.success.entrySet()) {
 
-          String other_element_key = other_element.getKey();
-          Set<IteratorScope> other_element_value = other_element.getValue();
+          java.lang.String other_element_key = other_element.getKey();
+          java.util.Set<IteratorScope> other_element_value = other_element.getValue();
 
-          String __this__success_copy_key = other_element_key;
+          java.lang.String __this__success_copy_key = other_element_key;
 
-          Set<IteratorScope> __this__success_copy_value = new HashSet<IteratorScope>(other_element_value.size());
+          java.util.Set<IteratorScope> __this__success_copy_value = new java.util.HashSet<IteratorScope>(other_element_value.size());
           for (IteratorScope other_element_value_element : other_element_value) {
             __this__success_copy_value.add(other_element_value_element);
           }
@@ -124348,18 +125169,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, Set<IteratorScope> val) {
+    public void putToSuccess(java.lang.String key, java.util.Set<IteratorScope> val) {
       if (this.success == null) {
-        this.success = new HashMap<String,Set<IteratorScope>>();
+        this.success = new java.util.HashMap<java.lang.String,java.util.Set<IteratorScope>>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,Set<IteratorScope>> getSuccess() {
+    public java.util.Map<java.lang.String,java.util.Set<IteratorScope>> getSuccess() {
       return this.success;
     }
 
-    public listNamespaceIterators_result setSuccess(Map<String,Set<IteratorScope>> success) {
+    public listNamespaceIterators_result setSuccess(java.util.Map<java.lang.String,java.util.Set<IteratorScope>> success) {
       this.success = success;
       return this;
     }
@@ -124451,13 +125272,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,Set<IteratorScope>>)value);
+          setSuccess((java.util.Map<java.lang.String,java.util.Set<IteratorScope>>)value);
         }
         break;
 
@@ -124488,7 +125309,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -124503,13 +125324,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -124522,11 +125343,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listNamespaceIterators_result)
@@ -124537,6 +125358,8 @@
     public boolean equals(listNamespaceIterators_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -124579,29 +125402,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -124612,7 +125431,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -124622,7 +125441,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -124632,7 +125451,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -124642,7 +125461,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -124660,16 +125479,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listNamespaceIterators_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaceIterators_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -124720,7 +125539,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -124728,13 +125547,13 @@
       }
     }
 
-    private static class listNamespaceIterators_resultStandardSchemeFactory implements SchemeFactory {
+    private static class listNamespaceIterators_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaceIterators_resultStandardScheme getScheme() {
         return new listNamespaceIterators_resultStandardScheme();
       }
     }
 
-    private static class listNamespaceIterators_resultStandardScheme extends StandardScheme<listNamespaceIterators_result> {
+    private static class listNamespaceIterators_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -124750,15 +125569,15 @@
               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;
+                  struct.success = new java.util.HashMap<java.lang.String,java.util.Set<IteratorScope>>(2*_map542.size);
+                  java.lang.String _key543;
+                  java.util.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);
+                      _val544 = new java.util.HashSet<IteratorScope>(2*_set546.size);
                       IteratorScope _elem547;
                       for (int _i548 = 0; _i548 < _set546.size; ++_i548)
                       {
@@ -124822,7 +125641,7 @@
           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())
+            for (java.util.Map.Entry<java.lang.String, java.util.Set<IteratorScope>> _iter549 : struct.success.entrySet())
             {
               oprot.writeString(_iter549.getKey());
               {
@@ -124859,18 +125678,18 @@
 
     }
 
-    private static class listNamespaceIterators_resultTupleSchemeFactory implements SchemeFactory {
+    private static class listNamespaceIterators_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaceIterators_resultTupleScheme getScheme() {
         return new listNamespaceIterators_resultTupleScheme();
       }
     }
 
-    private static class listNamespaceIterators_resultTupleScheme extends TupleScheme<listNamespaceIterators_result> {
+    private static class listNamespaceIterators_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -124887,7 +125706,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, Set<IteratorScope>> _iter551 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.util.Set<IteratorScope>> _iter551 : struct.success.entrySet())
             {
               oprot.writeString(_iter551.getKey());
               {
@@ -124913,20 +125732,20 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.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;
+            struct.success = new java.util.HashMap<java.lang.String,java.util.Set<IteratorScope>>(2*_map553.size);
+            java.lang.String _key554;
+            java.util.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);
+                _val555 = new java.util.HashSet<IteratorScope>(2*_set557.size);
                 IteratorScope _elem558;
                 for (int _i559 = 0; _i559 < _set557.size; ++_i559)
                 {
@@ -124957,6 +125776,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class checkNamespaceIteratorConflicts_args implements org.apache.thrift.TBase<checkNamespaceIteratorConflicts_args, checkNamespaceIteratorConflicts_args._Fields>, java.io.Serializable, Cloneable, Comparable<checkNamespaceIteratorConflicts_args>   {
@@ -124967,16 +125789,13 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new checkNamespaceIteratorConflicts_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new checkNamespaceIteratorConflicts_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String namespaceName; // required
     public IteratorSetting setting; // required
-    public Set<IteratorScope> scopes; // required
+    public java.util.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 {
@@ -124985,10 +125804,10 @@
       SETTING((short)3, "setting"),
       SCOPES((short)4, "scopes");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -125017,21 +125836,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -125040,15 +125859,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -125058,7 +125877,7 @@
       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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkNamespaceIteratorConflicts_args.class, metaDataMap);
     }
 
@@ -125066,10 +125885,10 @@
     }
 
     public checkNamespaceIteratorConflicts_args(
-      ByteBuffer login,
-      String namespaceName,
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName,
       IteratorSetting setting,
-      Set<IteratorScope> scopes)
+      java.util.Set<IteratorScope> scopes)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -125092,7 +125911,7 @@
         this.setting = new IteratorSetting(other.setting);
       }
       if (other.isSetScopes()) {
-        Set<IteratorScope> __this__scopes = new HashSet<IteratorScope>(other.scopes.size());
+        java.util.Set<IteratorScope> __this__scopes = new java.util.HashSet<IteratorScope>(other.scopes.size());
         for (IteratorScope other_element : other.scopes) {
           __this__scopes.add(other_element);
         }
@@ -125117,16 +125936,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public checkNamespaceIteratorConflicts_args setLogin(ByteBuffer login) {
+    public checkNamespaceIteratorConflicts_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -125146,11 +125965,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public checkNamespaceIteratorConflicts_args setNamespaceName(String namespaceName) {
+    public checkNamespaceIteratorConflicts_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -125204,16 +126023,16 @@
 
     public void addToScopes(IteratorScope elem) {
       if (this.scopes == null) {
-        this.scopes = new HashSet<IteratorScope>();
+        this.scopes = new java.util.HashSet<IteratorScope>();
       }
       this.scopes.add(elem);
     }
 
-    public Set<IteratorScope> getScopes() {
+    public java.util.Set<IteratorScope> getScopes() {
       return this.scopes;
     }
 
-    public checkNamespaceIteratorConflicts_args setScopes(Set<IteratorScope> scopes) {
+    public checkNamespaceIteratorConflicts_args setScopes(java.util.Set<IteratorScope> scopes) {
       this.scopes = scopes;
       return this;
     }
@@ -125233,13 +126052,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -125247,7 +126070,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -125263,14 +126086,14 @@
         if (value == null) {
           unsetScopes();
         } else {
-          setScopes((Set<IteratorScope>)value);
+          setScopes((java.util.Set<IteratorScope>)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -125285,13 +126108,13 @@
         return getScopes();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -125304,11 +126127,11 @@
       case SCOPES:
         return isSetScopes();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof checkNamespaceIteratorConflicts_args)
@@ -125319,6 +126142,8 @@
     public boolean equals(checkNamespaceIteratorConflicts_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -125361,29 +126186,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_setting = true && (isSetSetting());
-      list.add(present_setting);
-      if (present_setting)
-        list.add(setting);
+      hashCode = hashCode * 8191 + ((isSetSetting()) ? 131071 : 524287);
+      if (isSetSetting())
+        hashCode = hashCode * 8191 + setting.hashCode();
 
-      boolean present_scopes = true && (isSetScopes());
-      list.add(present_scopes);
-      if (present_scopes)
-        list.add(scopes);
+      hashCode = hashCode * 8191 + ((isSetScopes()) ? 131071 : 524287);
+      if (isSetScopes())
+        hashCode = hashCode * 8191 + scopes.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -125394,7 +126215,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -125404,7 +126225,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -125414,7 +126235,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
+      lastComparison = java.lang.Boolean.valueOf(isSetSetting()).compareTo(other.isSetSetting());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -125424,7 +126245,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
+      lastComparison = java.lang.Boolean.valueOf(isSetScopes()).compareTo(other.isSetScopes());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -125442,16 +126263,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("checkNamespaceIteratorConflicts_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("checkNamespaceIteratorConflicts_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -125505,7 +126326,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -125513,13 +126334,13 @@
       }
     }
 
-    private static class checkNamespaceIteratorConflicts_argsStandardSchemeFactory implements SchemeFactory {
+    private static class checkNamespaceIteratorConflicts_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public checkNamespaceIteratorConflicts_argsStandardScheme getScheme() {
         return new checkNamespaceIteratorConflicts_argsStandardScheme();
       }
     }
 
-    private static class checkNamespaceIteratorConflicts_argsStandardScheme extends StandardScheme<checkNamespaceIteratorConflicts_args> {
+    private static class checkNamespaceIteratorConflicts_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -125560,7 +126381,7 @@
               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);
+                  struct.scopes = new java.util.HashSet<IteratorScope>(2*_set560.size);
                   IteratorScope _elem561;
                   for (int _i562 = 0; _i562 < _set560.size; ++_i562)
                   {
@@ -125622,18 +126443,18 @@
 
     }
 
-    private static class checkNamespaceIteratorConflicts_argsTupleSchemeFactory implements SchemeFactory {
+    private static class checkNamespaceIteratorConflicts_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public checkNamespaceIteratorConflicts_argsTupleScheme getScheme() {
         return new checkNamespaceIteratorConflicts_argsTupleScheme();
       }
     }
 
-    private static class checkNamespaceIteratorConflicts_argsTupleScheme extends TupleScheme<checkNamespaceIteratorConflicts_args> {
+    private static class checkNamespaceIteratorConflicts_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -125669,8 +126490,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -125687,7 +126508,7 @@
         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);
+            struct.scopes = new java.util.HashSet<IteratorScope>(2*_set565.size);
             IteratorScope _elem566;
             for (int _i567 = 0; _i567 < _set565.size; ++_i567)
             {
@@ -125700,6 +126521,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class checkNamespaceIteratorConflicts_result implements org.apache.thrift.TBase<checkNamespaceIteratorConflicts_result, checkNamespaceIteratorConflicts_result._Fields>, java.io.Serializable, Cloneable, Comparable<checkNamespaceIteratorConflicts_result>   {
@@ -125709,11 +126533,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new checkNamespaceIteratorConflicts_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new checkNamespaceIteratorConflicts_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -125725,10 +126546,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -125755,21 +126576,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -125778,22 +126599,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(checkNamespaceIteratorConflicts_result.class, metaDataMap);
     }
 
@@ -125909,7 +126730,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -125938,7 +126759,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -125950,13 +126771,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -125967,11 +126788,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof checkNamespaceIteratorConflicts_result)
@@ -125982,6 +126803,8 @@
     public boolean equals(checkNamespaceIteratorConflicts_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -126015,24 +126838,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -126043,7 +126863,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -126053,7 +126873,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -126063,7 +126883,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -126081,16 +126901,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("checkNamespaceIteratorConflicts_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("checkNamespaceIteratorConflicts_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -126133,7 +126953,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -126141,13 +126961,13 @@
       }
     }
 
-    private static class checkNamespaceIteratorConflicts_resultStandardSchemeFactory implements SchemeFactory {
+    private static class checkNamespaceIteratorConflicts_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public checkNamespaceIteratorConflicts_resultStandardScheme getScheme() {
         return new checkNamespaceIteratorConflicts_resultStandardScheme();
       }
     }
 
-    private static class checkNamespaceIteratorConflicts_resultStandardScheme extends StandardScheme<checkNamespaceIteratorConflicts_result> {
+    private static class checkNamespaceIteratorConflicts_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -126222,18 +127042,18 @@
 
     }
 
-    private static class checkNamespaceIteratorConflicts_resultTupleSchemeFactory implements SchemeFactory {
+    private static class checkNamespaceIteratorConflicts_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public checkNamespaceIteratorConflicts_resultTupleScheme getScheme() {
         return new checkNamespaceIteratorConflicts_resultTupleScheme();
       }
     }
 
-    private static class checkNamespaceIteratorConflicts_resultTupleScheme extends TupleScheme<checkNamespaceIteratorConflicts_result> {
+    private static class checkNamespaceIteratorConflicts_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -126257,8 +127077,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -126277,6 +127097,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class addNamespaceConstraint_args implements org.apache.thrift.TBase<addNamespaceConstraint_args, addNamespaceConstraint_args._Fields>, java.io.Serializable, Cloneable, Comparable<addNamespaceConstraint_args>   {
@@ -126286,15 +127109,12 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addNamespaceConstraint_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addNamespaceConstraint_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
-    public String constraintClassName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String namespaceName; // required
+    public java.lang.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 {
@@ -126302,10 +127122,10 @@
       NAMESPACE_NAME((short)2, "namespaceName"),
       CONSTRAINT_CLASS_NAME((short)3, "constraintClassName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -126332,21 +127152,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -126355,22 +127175,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addNamespaceConstraint_args.class, metaDataMap);
     }
 
@@ -126378,9 +127198,9 @@
     }
 
     public addNamespaceConstraint_args(
-      ByteBuffer login,
-      String namespaceName,
-      String constraintClassName)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName,
+      java.lang.String constraintClassName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -126419,16 +127239,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public addNamespaceConstraint_args setLogin(ByteBuffer login) {
+    public addNamespaceConstraint_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -126448,11 +127268,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public addNamespaceConstraint_args setNamespaceName(String namespaceName) {
+    public addNamespaceConstraint_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -126472,11 +127292,11 @@
       }
     }
 
-    public String getConstraintClassName() {
+    public java.lang.String getConstraintClassName() {
       return this.constraintClassName;
     }
 
-    public addNamespaceConstraint_args setConstraintClassName(String constraintClassName) {
+    public addNamespaceConstraint_args setConstraintClassName(java.lang.String constraintClassName) {
       this.constraintClassName = constraintClassName;
       return this;
     }
@@ -126496,13 +127316,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -126510,7 +127334,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -126518,14 +127342,14 @@
         if (value == null) {
           unsetConstraintClassName();
         } else {
-          setConstraintClassName((String)value);
+          setConstraintClassName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -126537,13 +127361,13 @@
         return getConstraintClassName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -126554,11 +127378,11 @@
       case CONSTRAINT_CLASS_NAME:
         return isSetConstraintClassName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof addNamespaceConstraint_args)
@@ -126569,6 +127393,8 @@
     public boolean equals(addNamespaceConstraint_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -126602,24 +127428,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_constraintClassName = true && (isSetConstraintClassName());
-      list.add(present_constraintClassName);
-      if (present_constraintClassName)
-        list.add(constraintClassName);
+      hashCode = hashCode * 8191 + ((isSetConstraintClassName()) ? 131071 : 524287);
+      if (isSetConstraintClassName())
+        hashCode = hashCode * 8191 + constraintClassName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -126630,7 +127453,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -126640,7 +127463,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -126650,7 +127473,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetConstraintClassName()).compareTo(other.isSetConstraintClassName());
+      lastComparison = java.lang.Boolean.valueOf(isSetConstraintClassName()).compareTo(other.isSetConstraintClassName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -126668,16 +127491,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("addNamespaceConstraint_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("addNamespaceConstraint_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -126720,7 +127543,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -126728,13 +127551,13 @@
       }
     }
 
-    private static class addNamespaceConstraint_argsStandardSchemeFactory implements SchemeFactory {
+    private static class addNamespaceConstraint_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addNamespaceConstraint_argsStandardScheme getScheme() {
         return new addNamespaceConstraint_argsStandardScheme();
       }
     }
 
-    private static class addNamespaceConstraint_argsStandardScheme extends StandardScheme<addNamespaceConstraint_args> {
+    private static class addNamespaceConstraint_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -126806,18 +127629,18 @@
 
     }
 
-    private static class addNamespaceConstraint_argsTupleSchemeFactory implements SchemeFactory {
+    private static class addNamespaceConstraint_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addNamespaceConstraint_argsTupleScheme getScheme() {
         return new addNamespaceConstraint_argsTupleScheme();
       }
     }
 
-    private static class addNamespaceConstraint_argsTupleScheme extends TupleScheme<addNamespaceConstraint_args> {
+    private static class addNamespaceConstraint_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -126841,8 +127664,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -126858,6 +127681,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class addNamespaceConstraint_result implements org.apache.thrift.TBase<addNamespaceConstraint_result, addNamespaceConstraint_result._Fields>, java.io.Serializable, Cloneable, Comparable<addNamespaceConstraint_result>   {
@@ -126868,11 +127694,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addNamespaceConstraint_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addNamespaceConstraint_resultTupleSchemeFactory();
 
     public int success; // required
     public AccumuloException ouch1; // required
@@ -126886,10 +127709,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -126918,21 +127741,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -126941,7 +127764,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -126949,18 +127772,18 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addNamespaceConstraint_result.class, metaDataMap);
     }
 
@@ -127022,16 +127845,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public AccumuloException getOuch1() {
@@ -127106,13 +127929,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Integer)value);
+          setSuccess((java.lang.Integer)value);
         }
         break;
 
@@ -127143,7 +127966,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -127158,13 +127981,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -127177,11 +128000,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof addNamespaceConstraint_result)
@@ -127192,6 +128015,8 @@
     public boolean equals(addNamespaceConstraint_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -127234,29 +128059,23 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + success;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -127267,7 +128086,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -127277,7 +128096,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -127287,7 +128106,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -127297,7 +128116,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -127315,16 +128134,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("addNamespaceConstraint_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("addNamespaceConstraint_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -127371,7 +128190,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -127381,13 +128200,13 @@
       }
     }
 
-    private static class addNamespaceConstraint_resultStandardSchemeFactory implements SchemeFactory {
+    private static class addNamespaceConstraint_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addNamespaceConstraint_resultStandardScheme getScheme() {
         return new addNamespaceConstraint_resultStandardScheme();
       }
     }
 
-    private static class addNamespaceConstraint_resultStandardScheme extends StandardScheme<addNamespaceConstraint_result> {
+    private static class addNamespaceConstraint_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -127475,18 +128294,18 @@
 
     }
 
-    private static class addNamespaceConstraint_resultTupleSchemeFactory implements SchemeFactory {
+    private static class addNamespaceConstraint_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public addNamespaceConstraint_resultTupleScheme getScheme() {
         return new addNamespaceConstraint_resultTupleScheme();
       }
     }
 
-    private static class addNamespaceConstraint_resultTupleScheme extends TupleScheme<addNamespaceConstraint_result> {
+    private static class addNamespaceConstraint_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -127516,8 +128335,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = iprot.readI32();
           struct.setSuccessIsSet(true);
@@ -127540,6 +128359,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeNamespaceConstraint_args implements org.apache.thrift.TBase<removeNamespaceConstraint_args, removeNamespaceConstraint_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceConstraint_args>   {
@@ -127549,14 +128371,11 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeNamespaceConstraint_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeNamespaceConstraint_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String namespaceName; // required
     public int id; // required
 
     /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -127565,10 +128384,10 @@
       NAMESPACE_NAME((short)2, "namespaceName"),
       ID((short)3, "id");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -127595,21 +128414,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -127618,7 +128437,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -127626,16 +128445,16 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceConstraint_args.class, metaDataMap);
     }
 
@@ -127643,8 +128462,8 @@
     }
 
     public removeNamespaceConstraint_args(
-      ByteBuffer login,
-      String namespaceName,
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName,
       int id)
     {
       this();
@@ -127685,16 +128504,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public removeNamespaceConstraint_args setLogin(ByteBuffer login) {
+    public removeNamespaceConstraint_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -127714,11 +128533,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public removeNamespaceConstraint_args setNamespaceName(String namespaceName) {
+    public removeNamespaceConstraint_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -127749,25 +128568,29 @@
     }
 
     public void unsetId() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ID_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __ID_ISSET_ID);
     }
 
     public void setIdIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ID_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __ID_ISSET_ID, value);
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -127775,7 +128598,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -127783,14 +128606,14 @@
         if (value == null) {
           unsetId();
         } else {
-          setId((Integer)value);
+          setId((java.lang.Integer)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -127802,13 +128625,13 @@
         return getId();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -127819,11 +128642,11 @@
       case ID:
         return isSetId();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeNamespaceConstraint_args)
@@ -127834,6 +128657,8 @@
     public boolean equals(removeNamespaceConstraint_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -127867,24 +128692,19 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_id = true;
-      list.add(present_id);
-      if (present_id)
-        list.add(id);
+      hashCode = hashCode * 8191 + id;
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -127895,7 +128715,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -127905,7 +128725,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -127915,7 +128735,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetId()).compareTo(other.isSetId());
+      lastComparison = java.lang.Boolean.valueOf(isSetId()).compareTo(other.isSetId());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -127933,16 +128753,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeNamespaceConstraint_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceConstraint_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -127981,7 +128801,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -127991,13 +128811,13 @@
       }
     }
 
-    private static class removeNamespaceConstraint_argsStandardSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceConstraint_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceConstraint_argsStandardScheme getScheme() {
         return new removeNamespaceConstraint_argsStandardScheme();
       }
     }
 
-    private static class removeNamespaceConstraint_argsStandardScheme extends StandardScheme<removeNamespaceConstraint_args> {
+    private static class removeNamespaceConstraint_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -128067,18 +128887,18 @@
 
     }
 
-    private static class removeNamespaceConstraint_argsTupleSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceConstraint_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceConstraint_argsTupleScheme getScheme() {
         return new removeNamespaceConstraint_argsTupleScheme();
       }
     }
 
-    private static class removeNamespaceConstraint_argsTupleScheme extends TupleScheme<removeNamespaceConstraint_args> {
+    private static class removeNamespaceConstraint_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -128102,8 +128922,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -128119,6 +128939,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class removeNamespaceConstraint_result implements org.apache.thrift.TBase<removeNamespaceConstraint_result, removeNamespaceConstraint_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeNamespaceConstraint_result>   {
@@ -128128,11 +128951,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeNamespaceConstraint_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeNamespaceConstraint_resultTupleSchemeFactory();
 
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
@@ -128144,10 +128964,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -128174,21 +128994,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -128197,22 +129017,22 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeNamespaceConstraint_result.class, metaDataMap);
     }
 
@@ -128328,7 +129148,7 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case OUCH1:
         if (value == null) {
@@ -128357,7 +129177,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case OUCH1:
         return getOuch1();
@@ -128369,13 +129189,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -128386,11 +129206,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof removeNamespaceConstraint_result)
@@ -128401,6 +129221,8 @@
     public boolean equals(removeNamespaceConstraint_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_ouch1 = true && this.isSetOuch1();
       boolean that_present_ouch1 = true && that.isSetOuch1();
@@ -128434,24 +129256,21 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -128462,7 +129281,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -128472,7 +129291,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -128482,7 +129301,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -128500,16 +129319,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("removeNamespaceConstraint_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeNamespaceConstraint_result(");
       boolean first = true;
 
       sb.append("ouch1:");
@@ -128552,7 +129371,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -128560,13 +129379,13 @@
       }
     }
 
-    private static class removeNamespaceConstraint_resultStandardSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceConstraint_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceConstraint_resultStandardScheme getScheme() {
         return new removeNamespaceConstraint_resultStandardScheme();
       }
     }
 
-    private static class removeNamespaceConstraint_resultStandardScheme extends StandardScheme<removeNamespaceConstraint_result> {
+    private static class removeNamespaceConstraint_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -128641,18 +129460,18 @@
 
     }
 
-    private static class removeNamespaceConstraint_resultTupleSchemeFactory implements SchemeFactory {
+    private static class removeNamespaceConstraint_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public removeNamespaceConstraint_resultTupleScheme getScheme() {
         return new removeNamespaceConstraint_resultTupleScheme();
       }
     }
 
-    private static class removeNamespaceConstraint_resultTupleScheme extends TupleScheme<removeNamespaceConstraint_result> {
+    private static class removeNamespaceConstraint_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetOuch1()) {
           optionals.set(0);
         }
@@ -128676,8 +129495,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
         if (incoming.get(0)) {
           struct.ouch1 = new AccumuloException();
           struct.ouch1.read(iprot);
@@ -128696,6 +129515,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listNamespaceConstraints_args implements org.apache.thrift.TBase<listNamespaceConstraints_args, listNamespaceConstraints_args._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaceConstraints_args>   {
@@ -128704,24 +129526,21 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listNamespaceConstraints_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listNamespaceConstraints_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.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>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -128746,21 +129565,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -128769,20 +129588,20 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaceConstraints_args.class, metaDataMap);
     }
 
@@ -128790,8 +129609,8 @@
     }
 
     public listNamespaceConstraints_args(
-      ByteBuffer login,
-      String namespaceName)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -128825,16 +129644,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public listNamespaceConstraints_args setLogin(ByteBuffer login) {
+    public listNamespaceConstraints_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -128854,11 +129673,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public listNamespaceConstraints_args setNamespaceName(String namespaceName) {
+    public listNamespaceConstraints_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -128878,13 +129697,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -128892,14 +129715,14 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -128908,13 +129731,13 @@
         return getNamespaceName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -128923,11 +129746,11 @@
       case NAMESPACE_NAME:
         return isSetNamespaceName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listNamespaceConstraints_args)
@@ -128938,6 +129761,8 @@
     public boolean equals(listNamespaceConstraints_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -128962,19 +129787,17 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -128985,7 +129808,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -128995,7 +129818,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -129013,16 +129836,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listNamespaceConstraints_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaceConstraints_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -129057,7 +129880,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -129065,13 +129888,13 @@
       }
     }
 
-    private static class listNamespaceConstraints_argsStandardSchemeFactory implements SchemeFactory {
+    private static class listNamespaceConstraints_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaceConstraints_argsStandardScheme getScheme() {
         return new listNamespaceConstraints_argsStandardScheme();
       }
     }
 
-    private static class listNamespaceConstraints_argsStandardScheme extends StandardScheme<listNamespaceConstraints_args> {
+    private static class listNamespaceConstraints_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -129130,18 +129953,18 @@
 
     }
 
-    private static class listNamespaceConstraints_argsTupleSchemeFactory implements SchemeFactory {
+    private static class listNamespaceConstraints_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaceConstraints_argsTupleScheme getScheme() {
         return new listNamespaceConstraints_argsTupleScheme();
       }
     }
 
-    private static class listNamespaceConstraints_argsTupleScheme extends TupleScheme<listNamespaceConstraints_args> {
+    private static class listNamespaceConstraints_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -129159,8 +129982,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -129172,6 +129995,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class listNamespaceConstraints_result implements org.apache.thrift.TBase<listNamespaceConstraints_result, listNamespaceConstraints_result._Fields>, java.io.Serializable, Cloneable, Comparable<listNamespaceConstraints_result>   {
@@ -129182,13 +130008,10 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new listNamespaceConstraints_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new listNamespaceConstraints_resultTupleSchemeFactory();
 
-    public Map<String,Integer> success; // required
+    public java.util.Map<java.lang.String,java.lang.Integer> success; // required
     public AccumuloException ouch1; // required
     public AccumuloSecurityException ouch2; // required
     public NamespaceNotFoundException ouch3; // required
@@ -129200,10 +130023,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -129232,21 +130055,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -129255,26 +130078,26 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(listNamespaceConstraints_result.class, metaDataMap);
     }
 
@@ -129282,7 +130105,7 @@
     }
 
     public listNamespaceConstraints_result(
-      Map<String,Integer> success,
+      java.util.Map<java.lang.String,java.lang.Integer> success,
       AccumuloException ouch1,
       AccumuloSecurityException ouch2,
       NamespaceNotFoundException ouch3)
@@ -129299,7 +130122,7 @@
      */
     public listNamespaceConstraints_result(listNamespaceConstraints_result other) {
       if (other.isSetSuccess()) {
-        Map<String,Integer> __this__success = new HashMap<String,Integer>(other.success);
+        java.util.Map<java.lang.String,java.lang.Integer> __this__success = new java.util.HashMap<java.lang.String,java.lang.Integer>(other.success);
         this.success = __this__success;
       }
       if (other.isSetOuch1()) {
@@ -129329,18 +130152,18 @@
       return (this.success == null) ? 0 : this.success.size();
     }
 
-    public void putToSuccess(String key, int val) {
+    public void putToSuccess(java.lang.String key, int val) {
       if (this.success == null) {
-        this.success = new HashMap<String,Integer>();
+        this.success = new java.util.HashMap<java.lang.String,java.lang.Integer>();
       }
       this.success.put(key, val);
     }
 
-    public Map<String,Integer> getSuccess() {
+    public java.util.Map<java.lang.String,java.lang.Integer> getSuccess() {
       return this.success;
     }
 
-    public listNamespaceConstraints_result setSuccess(Map<String,Integer> success) {
+    public listNamespaceConstraints_result setSuccess(java.util.Map<java.lang.String,java.lang.Integer> success) {
       this.success = success;
       return this;
     }
@@ -129432,13 +130255,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Map<String,Integer>)value);
+          setSuccess((java.util.Map<java.lang.String,java.lang.Integer>)value);
         }
         break;
 
@@ -129469,7 +130292,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return getSuccess();
@@ -129484,13 +130307,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -129503,11 +130326,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof listNamespaceConstraints_result)
@@ -129518,6 +130341,8 @@
     public boolean equals(listNamespaceConstraints_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true && this.isSetSuccess();
       boolean that_present_success = true && that.isSetSuccess();
@@ -129560,29 +130385,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true && (isSetSuccess());
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -129593,7 +130414,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -129603,7 +130424,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -129613,7 +130434,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -129623,7 +130444,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -129641,16 +130462,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("listNamespaceConstraints_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("listNamespaceConstraints_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -129701,7 +130522,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -129709,13 +130530,13 @@
       }
     }
 
-    private static class listNamespaceConstraints_resultStandardSchemeFactory implements SchemeFactory {
+    private static class listNamespaceConstraints_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaceConstraints_resultStandardScheme getScheme() {
         return new listNamespaceConstraints_resultStandardScheme();
       }
     }
 
-    private static class listNamespaceConstraints_resultStandardScheme extends StandardScheme<listNamespaceConstraints_result> {
+    private static class listNamespaceConstraints_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -129731,8 +130552,8 @@
               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;
+                  struct.success = new java.util.HashMap<java.lang.String,java.lang.Integer>(2*_map568.size);
+                  java.lang.String _key569;
                   int _val570;
                   for (int _i571 = 0; _i571 < _map568.size; ++_i571)
                   {
@@ -129793,7 +130614,7 @@
           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())
+            for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter572 : struct.success.entrySet())
             {
               oprot.writeString(_iter572.getKey());
               oprot.writeI32(_iter572.getValue());
@@ -129823,18 +130644,18 @@
 
     }
 
-    private static class listNamespaceConstraints_resultTupleSchemeFactory implements SchemeFactory {
+    private static class listNamespaceConstraints_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public listNamespaceConstraints_resultTupleScheme getScheme() {
         return new listNamespaceConstraints_resultTupleScheme();
       }
     }
 
-    private static class listNamespaceConstraints_resultTupleScheme extends TupleScheme<listNamespaceConstraints_result> {
+    private static class listNamespaceConstraints_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -129851,7 +130672,7 @@
         if (struct.isSetSuccess()) {
           {
             oprot.writeI32(struct.success.size());
-            for (Map.Entry<String, Integer> _iter573 : struct.success.entrySet())
+            for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter573 : struct.success.entrySet())
             {
               oprot.writeString(_iter573.getKey());
               oprot.writeI32(_iter573.getValue());
@@ -129871,13 +130692,13 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.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;
+            struct.success = new java.util.HashMap<java.lang.String,java.lang.Integer>(2*_map574.size);
+            java.lang.String _key575;
             int _val576;
             for (int _i577 = 0; _i577 < _map574.size; ++_i577)
             {
@@ -129906,6 +130727,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class testNamespaceClassLoad_args implements org.apache.thrift.TBase<testNamespaceClassLoad_args, testNamespaceClassLoad_args._Fields>, java.io.Serializable, Cloneable, Comparable<testNamespaceClassLoad_args>   {
@@ -129916,16 +130740,13 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new testNamespaceClassLoad_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new testNamespaceClassLoad_argsTupleSchemeFactory();
 
-    public ByteBuffer login; // required
-    public String namespaceName; // required
-    public String className; // required
-    public String asTypeName; // required
+    public java.nio.ByteBuffer login; // required
+    public java.lang.String namespaceName; // required
+    public java.lang.String className; // required
+    public java.lang.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 {
@@ -129934,10 +130755,10 @@
       CLASS_NAME((short)3, "className"),
       AS_TYPE_NAME((short)4, "asTypeName");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -129966,21 +130787,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -129989,15 +130810,15 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
 
     // isset id assignments
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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, 
@@ -130006,7 +130827,7 @@
           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);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testNamespaceClassLoad_args.class, metaDataMap);
     }
 
@@ -130014,10 +130835,10 @@
     }
 
     public testNamespaceClassLoad_args(
-      ByteBuffer login,
-      String namespaceName,
-      String className,
-      String asTypeName)
+      java.nio.ByteBuffer login,
+      java.lang.String namespaceName,
+      java.lang.String className,
+      java.lang.String asTypeName)
     {
       this();
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
@@ -130061,16 +130882,16 @@
       return login == null ? null : login.array();
     }
 
-    public ByteBuffer bufferForLogin() {
+    public java.nio.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));
+      this.login = login == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(login.clone());
       return this;
     }
 
-    public testNamespaceClassLoad_args setLogin(ByteBuffer login) {
+    public testNamespaceClassLoad_args setLogin(java.nio.ByteBuffer login) {
       this.login = org.apache.thrift.TBaseHelper.copyBinary(login);
       return this;
     }
@@ -130090,11 +130911,11 @@
       }
     }
 
-    public String getNamespaceName() {
+    public java.lang.String getNamespaceName() {
       return this.namespaceName;
     }
 
-    public testNamespaceClassLoad_args setNamespaceName(String namespaceName) {
+    public testNamespaceClassLoad_args setNamespaceName(java.lang.String namespaceName) {
       this.namespaceName = namespaceName;
       return this;
     }
@@ -130114,11 +130935,11 @@
       }
     }
 
-    public String getClassName() {
+    public java.lang.String getClassName() {
       return this.className;
     }
 
-    public testNamespaceClassLoad_args setClassName(String className) {
+    public testNamespaceClassLoad_args setClassName(java.lang.String className) {
       this.className = className;
       return this;
     }
@@ -130138,11 +130959,11 @@
       }
     }
 
-    public String getAsTypeName() {
+    public java.lang.String getAsTypeName() {
       return this.asTypeName;
     }
 
-    public testNamespaceClassLoad_args setAsTypeName(String asTypeName) {
+    public testNamespaceClassLoad_args setAsTypeName(java.lang.String asTypeName) {
       this.asTypeName = asTypeName;
       return this;
     }
@@ -130162,13 +130983,17 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case LOGIN:
         if (value == null) {
           unsetLogin();
         } else {
-          setLogin((ByteBuffer)value);
+          if (value instanceof byte[]) {
+            setLogin((byte[])value);
+          } else {
+            setLogin((java.nio.ByteBuffer)value);
+          }
         }
         break;
 
@@ -130176,7 +131001,7 @@
         if (value == null) {
           unsetNamespaceName();
         } else {
-          setNamespaceName((String)value);
+          setNamespaceName((java.lang.String)value);
         }
         break;
 
@@ -130184,7 +131009,7 @@
         if (value == null) {
           unsetClassName();
         } else {
-          setClassName((String)value);
+          setClassName((java.lang.String)value);
         }
         break;
 
@@ -130192,14 +131017,14 @@
         if (value == null) {
           unsetAsTypeName();
         } else {
-          setAsTypeName((String)value);
+          setAsTypeName((java.lang.String)value);
         }
         break;
 
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case LOGIN:
         return getLogin();
@@ -130214,13 +131039,13 @@
         return getAsTypeName();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -130233,11 +131058,11 @@
       case AS_TYPE_NAME:
         return isSetAsTypeName();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof testNamespaceClassLoad_args)
@@ -130248,6 +131073,8 @@
     public boolean equals(testNamespaceClassLoad_args that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_login = true && this.isSetLogin();
       boolean that_present_login = true && that.isSetLogin();
@@ -130290,29 +131117,25 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_login = true && (isSetLogin());
-      list.add(present_login);
-      if (present_login)
-        list.add(login);
+      hashCode = hashCode * 8191 + ((isSetLogin()) ? 131071 : 524287);
+      if (isSetLogin())
+        hashCode = hashCode * 8191 + login.hashCode();
 
-      boolean present_namespaceName = true && (isSetNamespaceName());
-      list.add(present_namespaceName);
-      if (present_namespaceName)
-        list.add(namespaceName);
+      hashCode = hashCode * 8191 + ((isSetNamespaceName()) ? 131071 : 524287);
+      if (isSetNamespaceName())
+        hashCode = hashCode * 8191 + namespaceName.hashCode();
 
-      boolean present_className = true && (isSetClassName());
-      list.add(present_className);
-      if (present_className)
-        list.add(className);
+      hashCode = hashCode * 8191 + ((isSetClassName()) ? 131071 : 524287);
+      if (isSetClassName())
+        hashCode = hashCode * 8191 + className.hashCode();
 
-      boolean present_asTypeName = true && (isSetAsTypeName());
-      list.add(present_asTypeName);
-      if (present_asTypeName)
-        list.add(asTypeName);
+      hashCode = hashCode * 8191 + ((isSetAsTypeName()) ? 131071 : 524287);
+      if (isSetAsTypeName())
+        hashCode = hashCode * 8191 + asTypeName.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -130323,7 +131146,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
+      lastComparison = java.lang.Boolean.valueOf(isSetLogin()).compareTo(other.isSetLogin());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -130333,7 +131156,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
+      lastComparison = java.lang.Boolean.valueOf(isSetNamespaceName()).compareTo(other.isSetNamespaceName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -130343,7 +131166,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
+      lastComparison = java.lang.Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -130353,7 +131176,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetAsTypeName()).compareTo(other.isSetAsTypeName());
+      lastComparison = java.lang.Boolean.valueOf(isSetAsTypeName()).compareTo(other.isSetAsTypeName());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -130371,16 +131194,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
     }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("testNamespaceClassLoad_args(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("testNamespaceClassLoad_args(");
       boolean first = true;
 
       sb.append("login:");
@@ -130431,7 +131254,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
       try {
         read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
       } catch (org.apache.thrift.TException te) {
@@ -130439,13 +131262,13 @@
       }
     }
 
-    private static class testNamespaceClassLoad_argsStandardSchemeFactory implements SchemeFactory {
+    private static class testNamespaceClassLoad_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testNamespaceClassLoad_argsStandardScheme getScheme() {
         return new testNamespaceClassLoad_argsStandardScheme();
       }
     }
 
-    private static class testNamespaceClassLoad_argsStandardScheme extends StandardScheme<testNamespaceClassLoad_args> {
+    private static class testNamespaceClassLoad_argsStandardScheme extends org.apache.thrift.scheme.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;
@@ -130530,18 +131353,18 @@
 
     }
 
-    private static class testNamespaceClassLoad_argsTupleSchemeFactory implements SchemeFactory {
+    private static class testNamespaceClassLoad_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testNamespaceClassLoad_argsTupleScheme getScheme() {
         return new testNamespaceClassLoad_argsTupleScheme();
       }
     }
 
-    private static class testNamespaceClassLoad_argsTupleScheme extends TupleScheme<testNamespaceClassLoad_args> {
+    private static class testNamespaceClassLoad_argsTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetLogin()) {
           optionals.set(0);
         }
@@ -130571,8 +131394,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.login = iprot.readBinary();
           struct.setLoginIsSet(true);
@@ -130592,6 +131415,9 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
   public static class testNamespaceClassLoad_result implements org.apache.thrift.TBase<testNamespaceClassLoad_result, testNamespaceClassLoad_result._Fields>, java.io.Serializable, Cloneable, Comparable<testNamespaceClassLoad_result>   {
@@ -130602,11 +131428,8 @@
     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());
-    }
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new testNamespaceClassLoad_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new testNamespaceClassLoad_resultTupleSchemeFactory();
 
     public boolean success; // required
     public AccumuloException ouch1; // required
@@ -130620,10 +131443,10 @@
       OUCH2((short)2, "ouch2"),
       OUCH3((short)3, "ouch3");
 
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
       static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
           byName.put(field.getFieldName(), field);
         }
       }
@@ -130652,21 +131475,21 @@
        */
       public static _Fields findByThriftIdOrThrow(int fieldId) {
         _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        if (fields == null) throw new java.lang.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) {
+      public static _Fields findByName(java.lang.String name) {
         return byName.get(name);
       }
 
       private final short _thriftId;
-      private final String _fieldName;
+      private final java.lang.String _fieldName;
 
-      _Fields(short thriftId, String fieldName) {
+      _Fields(short thriftId, java.lang.String fieldName) {
         _thriftId = thriftId;
         _fieldName = fieldName;
       }
@@ -130675,7 +131498,7 @@
         return _thriftId;
       }
 
-      public String getFieldName() {
+      public java.lang.String getFieldName() {
         return _fieldName;
       }
     }
@@ -130683,18 +131506,18 @@
     // 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;
+    public static final java.util.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);
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloException.class)));
       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)));
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AccumuloSecurityException.class)));
       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);
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, NamespaceNotFoundException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
       org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(testNamespaceClassLoad_result.class, metaDataMap);
     }
 
@@ -130756,16 +131579,16 @@
     }
 
     public void unsetSuccess() {
-      __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+      __isset_bitfield = org.apache.thrift.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);
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
     }
 
     public void setSuccessIsSet(boolean value) {
-      __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
     }
 
     public AccumuloException getOuch1() {
@@ -130840,13 +131663,13 @@
       }
     }
 
-    public void setFieldValue(_Fields field, Object value) {
+    public void setFieldValue(_Fields field, java.lang.Object value) {
       switch (field) {
       case SUCCESS:
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((Boolean)value);
+          setSuccess((java.lang.Boolean)value);
         }
         break;
 
@@ -130877,7 +131700,7 @@
       }
     }
 
-    public Object getFieldValue(_Fields field) {
+    public java.lang.Object getFieldValue(_Fields field) {
       switch (field) {
       case SUCCESS:
         return isSuccess();
@@ -130892,13 +131715,13 @@
         return getOuch3();
 
       }
-      throw new IllegalStateException();
+      throw new java.lang.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();
+        throw new java.lang.IllegalArgumentException();
       }
 
       switch (field) {
@@ -130911,11 +131734,11 @@
       case OUCH3:
         return isSetOuch3();
       }
-      throw new IllegalStateException();
+      throw new java.lang.IllegalStateException();
     }
 
     @Override
-    public boolean equals(Object that) {
+    public boolean equals(java.lang.Object that) {
       if (that == null)
         return false;
       if (that instanceof testNamespaceClassLoad_result)
@@ -130926,6 +131749,8 @@
     public boolean equals(testNamespaceClassLoad_result that) {
       if (that == null)
         return false;
+      if (this == that)
+        return true;
 
       boolean this_present_success = true;
       boolean that_present_success = true;
@@ -130968,29 +131793,23 @@
 
     @Override
     public int hashCode() {
-      List<Object> list = new ArrayList<Object>();
+      int hashCode = 1;
 
-      boolean present_success = true;
-      list.add(present_success);
-      if (present_success)
-        list.add(success);
+      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);
 
-      boolean present_ouch1 = true && (isSetOuch1());
-      list.add(present_ouch1);
-      if (present_ouch1)
-        list.add(ouch1);
+      hashCode = hashCode * 8191 + ((isSetOuch1()) ? 131071 : 524287);
+      if (isSetOuch1())
+        hashCode = hashCode * 8191 + ouch1.hashCode();
 
-      boolean present_ouch2 = true && (isSetOuch2());
-      list.add(present_ouch2);
-      if (present_ouch2)
-        list.add(ouch2);
+      hashCode = hashCode * 8191 + ((isSetOuch2()) ? 131071 : 524287);
+      if (isSetOuch2())
+        hashCode = hashCode * 8191 + ouch2.hashCode();
 
-      boolean present_ouch3 = true && (isSetOuch3());
-      list.add(present_ouch3);
-      if (present_ouch3)
-        list.add(ouch3);
+      hashCode = hashCode * 8191 + ((isSetOuch3()) ? 131071 : 524287);
+      if (isSetOuch3())
+        hashCode = hashCode * 8191 + ouch3.hashCode();
 
-      return list.hashCode();
+      return hashCode;
     }
 
     @Override
@@ -131001,7 +131820,7 @@
 
       int lastComparison = 0;
 
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -131011,7 +131830,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch1()).compareTo(other.isSetOuch1());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -131021,7 +131840,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch2()).compareTo(other.isSetOuch2());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -131031,7 +131850,7 @@
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch3()).compareTo(other.isSetOuch3());
       if (lastComparison != 0) {
         return lastComparison;
       }
@@ -131049,16 +131868,16 @@
     }
 
     public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+      scheme(iprot).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);
+      scheme(oprot).write(oprot, this);
       }
 
     @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("testNamespaceClassLoad_result(");
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("testNamespaceClassLoad_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -131105,7 +131924,7 @@
       }
     }
 
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -131115,13 +131934,13 @@
       }
     }
 
-    private static class testNamespaceClassLoad_resultStandardSchemeFactory implements SchemeFactory {
+    private static class testNamespaceClassLoad_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testNamespaceClassLoad_resultStandardScheme getScheme() {
         return new testNamespaceClassLoad_resultStandardScheme();
       }
     }
 
-    private static class testNamespaceClassLoad_resultStandardScheme extends StandardScheme<testNamespaceClassLoad_result> {
+    private static class testNamespaceClassLoad_resultStandardScheme extends org.apache.thrift.scheme.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;
@@ -131209,18 +132028,18 @@
 
     }
 
-    private static class testNamespaceClassLoad_resultTupleSchemeFactory implements SchemeFactory {
+    private static class testNamespaceClassLoad_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
       public testNamespaceClassLoad_resultTupleScheme getScheme() {
         return new testNamespaceClassLoad_resultTupleScheme();
       }
     }
 
-    private static class testNamespaceClassLoad_resultTupleScheme extends TupleScheme<testNamespaceClassLoad_result> {
+    private static class testNamespaceClassLoad_resultTupleScheme extends org.apache.thrift.scheme.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();
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
         if (struct.isSetSuccess()) {
           optionals.set(0);
         }
@@ -131250,8 +132069,8 @@
 
       @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);
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
           struct.success = iprot.readBool();
           struct.setSuccessIsSet(true);
@@ -131274,6 +132093,10 @@
       }
     }
 
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
   }
 
+  private static void unusedMethod() {}
 }
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 f77a908..7ac823d 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloSecurityException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/AccumuloSecurityException.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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 AccumuloSecurityException extends TException implements org.apache.thrift.TBase<AccumuloSecurityException, AccumuloSecurityException._Fields>, java.io.Serializable, Cloneable, Comparable<AccumuloSecurityException> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class AccumuloSecurityException extends org.apache.thrift.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);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new AccumuloSecurityExceptionStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new AccumuloSecurityExceptionTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new AccumuloSecurityExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new AccumuloSecurityExceptionTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(AccumuloSecurityException.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public AccumuloSecurityException(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public AccumuloSecurityException setMsg(String msg) {
+  public AccumuloSecurityException setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof AccumuloSecurityException)
@@ -231,6 +201,8 @@
   public boolean equals(AccumuloSecurityException that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("AccumuloSecurityException(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("AccumuloSecurityException(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class AccumuloSecurityExceptionStandardSchemeFactory implements SchemeFactory {
+  private static class AccumuloSecurityExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public AccumuloSecurityExceptionStandardScheme getScheme() {
       return new AccumuloSecurityExceptionStandardScheme();
     }
   }
 
-  private static class AccumuloSecurityExceptionStandardScheme extends StandardScheme<AccumuloSecurityException> {
+  private static class AccumuloSecurityExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<AccumuloSecurityException> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, AccumuloSecurityException struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class AccumuloSecurityExceptionTupleSchemeFactory implements SchemeFactory {
+  private static class AccumuloSecurityExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public AccumuloSecurityExceptionTupleScheme getScheme() {
       return new AccumuloSecurityExceptionTupleScheme();
     }
   }
 
-  private static class AccumuloSecurityExceptionTupleScheme extends TupleScheme<AccumuloSecurityException> {
+  private static class AccumuloSecurityExceptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<AccumuloSecurityException> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, AccumuloSecurityException struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, AccumuloSecurityException struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(1);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 986b68c..8ef3a9d 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ActiveCompaction.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ActiveCompaction.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -65,16 +38,13 @@
   private static final org.apache.thrift.protocol.TField ENTRIES_WRITTEN_FIELD_DESC = new org.apache.thrift.protocol.TField("entriesWritten", org.apache.thrift.protocol.TType.I64, (short)9);
   private static final org.apache.thrift.protocol.TField ITERATORS_FIELD_DESC = new org.apache.thrift.protocol.TField("iterators", org.apache.thrift.protocol.TType.LIST, (short)10);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new ActiveCompactionStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new ActiveCompactionTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ActiveCompactionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ActiveCompactionTupleSchemeFactory();
 
   public KeyExtent extent; // required
   public long age; // required
-  public List<String> inputFiles; // required
-  public String outputFile; // required
+  public java.util.List<java.lang.String> inputFiles; // required
+  public java.lang.String outputFile; // required
   /**
    * 
    * @see CompactionType
@@ -85,10 +55,10 @@
    * @see CompactionReason
    */
   public CompactionReason reason; // required
-  public String localityGroup; // required
+  public java.lang.String localityGroup; // required
   public long entriesRead; // required
   public long entriesWritten; // required
-  public List<IteratorSetting> iterators; // required
+  public java.util.List<IteratorSetting> iterators; // 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 {
@@ -111,10 +81,10 @@
     ENTRIES_WRITTEN((short)9, "entriesWritten"),
     ITERATORS((short)10, "iterators");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -155,21 +125,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -178,7 +148,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -188,9 +158,9 @@
   private static final int __ENTRIESREAD_ISSET_ID = 1;
   private static final int __ENTRIESWRITTEN_ISSET_ID = 2;
   private byte __isset_bitfield = 0;
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.EXTENT, new org.apache.thrift.meta_data.FieldMetaData("extent", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KeyExtent.class)));
     tmpMap.put(_Fields.AGE, new org.apache.thrift.meta_data.FieldMetaData("age", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -213,7 +183,7 @@
     tmpMap.put(_Fields.ITERATORS, new org.apache.thrift.meta_data.FieldMetaData("iterators", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
             new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class))));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ActiveCompaction.class, metaDataMap);
   }
 
@@ -223,14 +193,14 @@
   public ActiveCompaction(
     KeyExtent extent,
     long age,
-    List<String> inputFiles,
-    String outputFile,
+    java.util.List<java.lang.String> inputFiles,
+    java.lang.String outputFile,
     CompactionType type,
     CompactionReason reason,
-    String localityGroup,
+    java.lang.String localityGroup,
     long entriesRead,
     long entriesWritten,
-    List<IteratorSetting> iterators)
+    java.util.List<IteratorSetting> iterators)
   {
     this();
     this.extent = extent;
@@ -258,7 +228,7 @@
     }
     this.age = other.age;
     if (other.isSetInputFiles()) {
-      List<String> __this__inputFiles = new ArrayList<String>(other.inputFiles);
+      java.util.List<java.lang.String> __this__inputFiles = new java.util.ArrayList<java.lang.String>(other.inputFiles);
       this.inputFiles = __this__inputFiles;
     }
     if (other.isSetOutputFile()) {
@@ -276,7 +246,7 @@
     this.entriesRead = other.entriesRead;
     this.entriesWritten = other.entriesWritten;
     if (other.isSetIterators()) {
-      List<IteratorSetting> __this__iterators = new ArrayList<IteratorSetting>(other.iterators.size());
+      java.util.List<IteratorSetting> __this__iterators = new java.util.ArrayList<IteratorSetting>(other.iterators.size());
       for (IteratorSetting other_element : other.iterators) {
         __this__iterators.add(new IteratorSetting(other_element));
       }
@@ -340,38 +310,38 @@
   }
 
   public void unsetAge() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGE_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __AGE_ISSET_ID);
   }
 
   /** Returns true if field age is set (has been assigned a value) and false otherwise */
   public boolean isSetAge() {
-    return EncodingUtils.testBit(__isset_bitfield, __AGE_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __AGE_ISSET_ID);
   }
 
   public void setAgeIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGE_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __AGE_ISSET_ID, value);
   }
 
   public int getInputFilesSize() {
     return (this.inputFiles == null) ? 0 : this.inputFiles.size();
   }
 
-  public java.util.Iterator<String> getInputFilesIterator() {
+  public java.util.Iterator<java.lang.String> getInputFilesIterator() {
     return (this.inputFiles == null) ? null : this.inputFiles.iterator();
   }
 
-  public void addToInputFiles(String elem) {
+  public void addToInputFiles(java.lang.String elem) {
     if (this.inputFiles == null) {
-      this.inputFiles = new ArrayList<String>();
+      this.inputFiles = new java.util.ArrayList<java.lang.String>();
     }
     this.inputFiles.add(elem);
   }
 
-  public List<String> getInputFiles() {
+  public java.util.List<java.lang.String> getInputFiles() {
     return this.inputFiles;
   }
 
-  public ActiveCompaction setInputFiles(List<String> inputFiles) {
+  public ActiveCompaction setInputFiles(java.util.List<java.lang.String> inputFiles) {
     this.inputFiles = inputFiles;
     return this;
   }
@@ -391,11 +361,11 @@
     }
   }
 
-  public String getOutputFile() {
+  public java.lang.String getOutputFile() {
     return this.outputFile;
   }
 
-  public ActiveCompaction setOutputFile(String outputFile) {
+  public ActiveCompaction setOutputFile(java.lang.String outputFile) {
     this.outputFile = outputFile;
     return this;
   }
@@ -479,11 +449,11 @@
     }
   }
 
-  public String getLocalityGroup() {
+  public java.lang.String getLocalityGroup() {
     return this.localityGroup;
   }
 
-  public ActiveCompaction setLocalityGroup(String localityGroup) {
+  public ActiveCompaction setLocalityGroup(java.lang.String localityGroup) {
     this.localityGroup = localityGroup;
     return this;
   }
@@ -514,16 +484,16 @@
   }
 
   public void unsetEntriesRead() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ENTRIESREAD_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __ENTRIESREAD_ISSET_ID);
   }
 
   /** Returns true if field entriesRead is set (has been assigned a value) and false otherwise */
   public boolean isSetEntriesRead() {
-    return EncodingUtils.testBit(__isset_bitfield, __ENTRIESREAD_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __ENTRIESREAD_ISSET_ID);
   }
 
   public void setEntriesReadIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ENTRIESREAD_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __ENTRIESREAD_ISSET_ID, value);
   }
 
   public long getEntriesWritten() {
@@ -537,16 +507,16 @@
   }
 
   public void unsetEntriesWritten() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ENTRIESWRITTEN_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __ENTRIESWRITTEN_ISSET_ID);
   }
 
   /** Returns true if field entriesWritten is set (has been assigned a value) and false otherwise */
   public boolean isSetEntriesWritten() {
-    return EncodingUtils.testBit(__isset_bitfield, __ENTRIESWRITTEN_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __ENTRIESWRITTEN_ISSET_ID);
   }
 
   public void setEntriesWrittenIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ENTRIESWRITTEN_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __ENTRIESWRITTEN_ISSET_ID, value);
   }
 
   public int getIteratorsSize() {
@@ -559,16 +529,16 @@
 
   public void addToIterators(IteratorSetting elem) {
     if (this.iterators == null) {
-      this.iterators = new ArrayList<IteratorSetting>();
+      this.iterators = new java.util.ArrayList<IteratorSetting>();
     }
     this.iterators.add(elem);
   }
 
-  public List<IteratorSetting> getIterators() {
+  public java.util.List<IteratorSetting> getIterators() {
     return this.iterators;
   }
 
-  public ActiveCompaction setIterators(List<IteratorSetting> iterators) {
+  public ActiveCompaction setIterators(java.util.List<IteratorSetting> iterators) {
     this.iterators = iterators;
     return this;
   }
@@ -588,7 +558,7 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case EXTENT:
       if (value == null) {
@@ -602,7 +572,7 @@
       if (value == null) {
         unsetAge();
       } else {
-        setAge((Long)value);
+        setAge((java.lang.Long)value);
       }
       break;
 
@@ -610,7 +580,7 @@
       if (value == null) {
         unsetInputFiles();
       } else {
-        setInputFiles((List<String>)value);
+        setInputFiles((java.util.List<java.lang.String>)value);
       }
       break;
 
@@ -618,7 +588,7 @@
       if (value == null) {
         unsetOutputFile();
       } else {
-        setOutputFile((String)value);
+        setOutputFile((java.lang.String)value);
       }
       break;
 
@@ -642,7 +612,7 @@
       if (value == null) {
         unsetLocalityGroup();
       } else {
-        setLocalityGroup((String)value);
+        setLocalityGroup((java.lang.String)value);
       }
       break;
 
@@ -650,7 +620,7 @@
       if (value == null) {
         unsetEntriesRead();
       } else {
-        setEntriesRead((Long)value);
+        setEntriesRead((java.lang.Long)value);
       }
       break;
 
@@ -658,7 +628,7 @@
       if (value == null) {
         unsetEntriesWritten();
       } else {
-        setEntriesWritten((Long)value);
+        setEntriesWritten((java.lang.Long)value);
       }
       break;
 
@@ -666,14 +636,14 @@
       if (value == null) {
         unsetIterators();
       } else {
-        setIterators((List<IteratorSetting>)value);
+        setIterators((java.util.List<IteratorSetting>)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case EXTENT:
       return getExtent();
@@ -706,13 +676,13 @@
       return getIterators();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -737,11 +707,11 @@
     case ITERATORS:
       return isSetIterators();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof ActiveCompaction)
@@ -752,6 +722,8 @@
   public boolean equals(ActiveCompaction that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_extent = true && this.isSetExtent();
     boolean that_present_extent = true && that.isSetExtent();
@@ -848,59 +820,43 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_extent = true && (isSetExtent());
-    list.add(present_extent);
-    if (present_extent)
-      list.add(extent);
+    hashCode = hashCode * 8191 + ((isSetExtent()) ? 131071 : 524287);
+    if (isSetExtent())
+      hashCode = hashCode * 8191 + extent.hashCode();
 
-    boolean present_age = true;
-    list.add(present_age);
-    if (present_age)
-      list.add(age);
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(age);
 
-    boolean present_inputFiles = true && (isSetInputFiles());
-    list.add(present_inputFiles);
-    if (present_inputFiles)
-      list.add(inputFiles);
+    hashCode = hashCode * 8191 + ((isSetInputFiles()) ? 131071 : 524287);
+    if (isSetInputFiles())
+      hashCode = hashCode * 8191 + inputFiles.hashCode();
 
-    boolean present_outputFile = true && (isSetOutputFile());
-    list.add(present_outputFile);
-    if (present_outputFile)
-      list.add(outputFile);
+    hashCode = hashCode * 8191 + ((isSetOutputFile()) ? 131071 : 524287);
+    if (isSetOutputFile())
+      hashCode = hashCode * 8191 + outputFile.hashCode();
 
-    boolean present_type = true && (isSetType());
-    list.add(present_type);
-    if (present_type)
-      list.add(type.getValue());
+    hashCode = hashCode * 8191 + ((isSetType()) ? 131071 : 524287);
+    if (isSetType())
+      hashCode = hashCode * 8191 + type.getValue();
 
-    boolean present_reason = true && (isSetReason());
-    list.add(present_reason);
-    if (present_reason)
-      list.add(reason.getValue());
+    hashCode = hashCode * 8191 + ((isSetReason()) ? 131071 : 524287);
+    if (isSetReason())
+      hashCode = hashCode * 8191 + reason.getValue();
 
-    boolean present_localityGroup = true && (isSetLocalityGroup());
-    list.add(present_localityGroup);
-    if (present_localityGroup)
-      list.add(localityGroup);
+    hashCode = hashCode * 8191 + ((isSetLocalityGroup()) ? 131071 : 524287);
+    if (isSetLocalityGroup())
+      hashCode = hashCode * 8191 + localityGroup.hashCode();
 
-    boolean present_entriesRead = true;
-    list.add(present_entriesRead);
-    if (present_entriesRead)
-      list.add(entriesRead);
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(entriesRead);
 
-    boolean present_entriesWritten = true;
-    list.add(present_entriesWritten);
-    if (present_entriesWritten)
-      list.add(entriesWritten);
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(entriesWritten);
 
-    boolean present_iterators = true && (isSetIterators());
-    list.add(present_iterators);
-    if (present_iterators)
-      list.add(iterators);
+    hashCode = hashCode * 8191 + ((isSetIterators()) ? 131071 : 524287);
+    if (isSetIterators())
+      hashCode = hashCode * 8191 + iterators.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -911,7 +867,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetExtent()).compareTo(other.isSetExtent());
+    lastComparison = java.lang.Boolean.valueOf(isSetExtent()).compareTo(other.isSetExtent());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -921,7 +877,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetAge()).compareTo(other.isSetAge());
+    lastComparison = java.lang.Boolean.valueOf(isSetAge()).compareTo(other.isSetAge());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -931,7 +887,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetInputFiles()).compareTo(other.isSetInputFiles());
+    lastComparison = java.lang.Boolean.valueOf(isSetInputFiles()).compareTo(other.isSetInputFiles());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -941,7 +897,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetOutputFile()).compareTo(other.isSetOutputFile());
+    lastComparison = java.lang.Boolean.valueOf(isSetOutputFile()).compareTo(other.isSetOutputFile());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -951,7 +907,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType());
+    lastComparison = java.lang.Boolean.valueOf(isSetType()).compareTo(other.isSetType());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -961,7 +917,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetReason()).compareTo(other.isSetReason());
+    lastComparison = java.lang.Boolean.valueOf(isSetReason()).compareTo(other.isSetReason());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -971,7 +927,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetLocalityGroup()).compareTo(other.isSetLocalityGroup());
+    lastComparison = java.lang.Boolean.valueOf(isSetLocalityGroup()).compareTo(other.isSetLocalityGroup());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -981,7 +937,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetEntriesRead()).compareTo(other.isSetEntriesRead());
+    lastComparison = java.lang.Boolean.valueOf(isSetEntriesRead()).compareTo(other.isSetEntriesRead());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -991,7 +947,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetEntriesWritten()).compareTo(other.isSetEntriesWritten());
+    lastComparison = java.lang.Boolean.valueOf(isSetEntriesWritten()).compareTo(other.isSetEntriesWritten());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1001,7 +957,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
+    lastComparison = java.lang.Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1019,16 +975,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("ActiveCompaction(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("ActiveCompaction(");
     boolean first = true;
 
     sb.append("extent:");
@@ -1118,7 +1074,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -1128,13 +1084,13 @@
     }
   }
 
-  private static class ActiveCompactionStandardSchemeFactory implements SchemeFactory {
+  private static class ActiveCompactionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ActiveCompactionStandardScheme getScheme() {
       return new ActiveCompactionStandardScheme();
     }
   }
 
-  private static class ActiveCompactionStandardScheme extends StandardScheme<ActiveCompaction> {
+  private static class ActiveCompactionStandardScheme extends org.apache.thrift.scheme.StandardScheme<ActiveCompaction> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, ActiveCompaction struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -1167,8 +1123,8 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list138 = iprot.readListBegin();
-                struct.inputFiles = new ArrayList<String>(_list138.size);
-                String _elem139;
+                struct.inputFiles = new java.util.ArrayList<java.lang.String>(_list138.size);
+                java.lang.String _elem139;
                 for (int _i140 = 0; _i140 < _list138.size; ++_i140)
                 {
                   _elem139 = iprot.readString();
@@ -1233,7 +1189,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list141 = iprot.readListBegin();
-                struct.iterators = new ArrayList<IteratorSetting>(_list141.size);
+                struct.iterators = new java.util.ArrayList<IteratorSetting>(_list141.size);
                 IteratorSetting _elem142;
                 for (int _i143 = 0; _i143 < _list141.size; ++_i143)
                 {
@@ -1275,7 +1231,7 @@
         oprot.writeFieldBegin(INPUT_FILES_FIELD_DESC);
         {
           oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.inputFiles.size()));
-          for (String _iter144 : struct.inputFiles)
+          for (java.lang.String _iter144 : struct.inputFiles)
           {
             oprot.writeString(_iter144);
           }
@@ -1327,18 +1283,18 @@
 
   }
 
-  private static class ActiveCompactionTupleSchemeFactory implements SchemeFactory {
+  private static class ActiveCompactionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ActiveCompactionTupleScheme getScheme() {
       return new ActiveCompactionTupleScheme();
     }
   }
 
-  private static class ActiveCompactionTupleScheme extends TupleScheme<ActiveCompaction> {
+  private static class ActiveCompactionTupleScheme extends org.apache.thrift.scheme.TupleScheme<ActiveCompaction> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, ActiveCompaction struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetExtent()) {
         optionals.set(0);
       }
@@ -1379,7 +1335,7 @@
       if (struct.isSetInputFiles()) {
         {
           oprot.writeI32(struct.inputFiles.size());
-          for (String _iter146 : struct.inputFiles)
+          for (java.lang.String _iter146 : struct.inputFiles)
           {
             oprot.writeString(_iter146);
           }
@@ -1416,8 +1372,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, ActiveCompaction struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(10);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(10);
       if (incoming.get(0)) {
         struct.extent = new KeyExtent();
         struct.extent.read(iprot);
@@ -1430,8 +1386,8 @@
       if (incoming.get(2)) {
         {
           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);
-          String _elem149;
+          struct.inputFiles = new java.util.ArrayList<java.lang.String>(_list148.size);
+          java.lang.String _elem149;
           for (int _i150 = 0; _i150 < _list148.size; ++_i150)
           {
             _elem149 = iprot.readString();
@@ -1467,7 +1423,7 @@
       if (incoming.get(9)) {
         {
           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);
+          struct.iterators = new java.util.ArrayList<IteratorSetting>(_list151.size);
           IteratorSetting _elem152;
           for (int _i153 = 0; _i153 < _list151.size; ++_i153)
           {
@@ -1481,5 +1437,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 9f4d892..66c8cc8 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ActiveScan.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ActiveScan.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -66,15 +39,12 @@
   private static final org.apache.thrift.protocol.TField ITERATORS_FIELD_DESC = new org.apache.thrift.protocol.TField("iterators", org.apache.thrift.protocol.TType.LIST, (short)10);
   private static final org.apache.thrift.protocol.TField AUTHORIZATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("authorizations", org.apache.thrift.protocol.TType.LIST, (short)11);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new ActiveScanStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new ActiveScanTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ActiveScanStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ActiveScanTupleSchemeFactory();
 
-  public String client; // required
-  public String user; // required
-  public String table; // required
+  public java.lang.String client; // required
+  public java.lang.String user; // required
+  public java.lang.String table; // required
   public long age; // required
   public long idleTime; // required
   /**
@@ -88,9 +58,9 @@
    */
   public ScanState state; // required
   public KeyExtent extent; // required
-  public List<Column> columns; // required
-  public List<IteratorSetting> iterators; // required
-  public List<ByteBuffer> authorizations; // required
+  public java.util.List<Column> columns; // required
+  public java.util.List<IteratorSetting> iterators; // required
+  public java.util.List<java.nio.ByteBuffer> authorizations; // 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 {
@@ -114,10 +84,10 @@
     ITERATORS((short)10, "iterators"),
     AUTHORIZATIONS((short)11, "authorizations");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -160,21 +130,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -183,7 +153,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -192,9 +162,9 @@
   private static final int __AGE_ISSET_ID = 0;
   private static final int __IDLETIME_ISSET_ID = 1;
   private byte __isset_bitfield = 0;
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.CLIENT, new org.apache.thrift.meta_data.FieldMetaData("client", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
     tmpMap.put(_Fields.USER, new org.apache.thrift.meta_data.FieldMetaData("user", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -220,7 +190,7 @@
     tmpMap.put(_Fields.AUTHORIZATIONS, new org.apache.thrift.meta_data.FieldMetaData("authorizations", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
             new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING            , true))));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ActiveScan.class, metaDataMap);
   }
 
@@ -228,17 +198,17 @@
   }
 
   public ActiveScan(
-    String client,
-    String user,
-    String table,
+    java.lang.String client,
+    java.lang.String user,
+    java.lang.String table,
     long age,
     long idleTime,
     ScanType type,
     ScanState state,
     KeyExtent extent,
-    List<Column> columns,
-    List<IteratorSetting> iterators,
-    List<ByteBuffer> authorizations)
+    java.util.List<Column> columns,
+    java.util.List<IteratorSetting> iterators,
+    java.util.List<java.nio.ByteBuffer> authorizations)
   {
     this();
     this.client = client;
@@ -282,21 +252,21 @@
       this.extent = new KeyExtent(other.extent);
     }
     if (other.isSetColumns()) {
-      List<Column> __this__columns = new ArrayList<Column>(other.columns.size());
+      java.util.List<Column> __this__columns = new java.util.ArrayList<Column>(other.columns.size());
       for (Column other_element : other.columns) {
         __this__columns.add(new Column(other_element));
       }
       this.columns = __this__columns;
     }
     if (other.isSetIterators()) {
-      List<IteratorSetting> __this__iterators = new ArrayList<IteratorSetting>(other.iterators.size());
+      java.util.List<IteratorSetting> __this__iterators = new java.util.ArrayList<IteratorSetting>(other.iterators.size());
       for (IteratorSetting other_element : other.iterators) {
         __this__iterators.add(new IteratorSetting(other_element));
       }
       this.iterators = __this__iterators;
     }
     if (other.isSetAuthorizations()) {
-      List<ByteBuffer> __this__authorizations = new ArrayList<ByteBuffer>(other.authorizations);
+      java.util.List<java.nio.ByteBuffer> __this__authorizations = new java.util.ArrayList<java.nio.ByteBuffer>(other.authorizations);
       this.authorizations = __this__authorizations;
     }
   }
@@ -322,11 +292,11 @@
     this.authorizations = null;
   }
 
-  public String getClient() {
+  public java.lang.String getClient() {
     return this.client;
   }
 
-  public ActiveScan setClient(String client) {
+  public ActiveScan setClient(java.lang.String client) {
     this.client = client;
     return this;
   }
@@ -346,11 +316,11 @@
     }
   }
 
-  public String getUser() {
+  public java.lang.String getUser() {
     return this.user;
   }
 
-  public ActiveScan setUser(String user) {
+  public ActiveScan setUser(java.lang.String user) {
     this.user = user;
     return this;
   }
@@ -370,11 +340,11 @@
     }
   }
 
-  public String getTable() {
+  public java.lang.String getTable() {
     return this.table;
   }
 
-  public ActiveScan setTable(String table) {
+  public ActiveScan setTable(java.lang.String table) {
     this.table = table;
     return this;
   }
@@ -405,16 +375,16 @@
   }
 
   public void unsetAge() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __AGE_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __AGE_ISSET_ID);
   }
 
   /** Returns true if field age is set (has been assigned a value) and false otherwise */
   public boolean isSetAge() {
-    return EncodingUtils.testBit(__isset_bitfield, __AGE_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __AGE_ISSET_ID);
   }
 
   public void setAgeIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __AGE_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __AGE_ISSET_ID, value);
   }
 
   public long getIdleTime() {
@@ -428,16 +398,16 @@
   }
 
   public void unsetIdleTime() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __IDLETIME_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __IDLETIME_ISSET_ID);
   }
 
   /** Returns true if field idleTime is set (has been assigned a value) and false otherwise */
   public boolean isSetIdleTime() {
-    return EncodingUtils.testBit(__isset_bitfield, __IDLETIME_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __IDLETIME_ISSET_ID);
   }
 
   public void setIdleTimeIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __IDLETIME_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __IDLETIME_ISSET_ID, value);
   }
 
   /**
@@ -538,16 +508,16 @@
 
   public void addToColumns(Column elem) {
     if (this.columns == null) {
-      this.columns = new ArrayList<Column>();
+      this.columns = new java.util.ArrayList<Column>();
     }
     this.columns.add(elem);
   }
 
-  public List<Column> getColumns() {
+  public java.util.List<Column> getColumns() {
     return this.columns;
   }
 
-  public ActiveScan setColumns(List<Column> columns) {
+  public ActiveScan setColumns(java.util.List<Column> columns) {
     this.columns = columns;
     return this;
   }
@@ -577,16 +547,16 @@
 
   public void addToIterators(IteratorSetting elem) {
     if (this.iterators == null) {
-      this.iterators = new ArrayList<IteratorSetting>();
+      this.iterators = new java.util.ArrayList<IteratorSetting>();
     }
     this.iterators.add(elem);
   }
 
-  public List<IteratorSetting> getIterators() {
+  public java.util.List<IteratorSetting> getIterators() {
     return this.iterators;
   }
 
-  public ActiveScan setIterators(List<IteratorSetting> iterators) {
+  public ActiveScan setIterators(java.util.List<IteratorSetting> iterators) {
     this.iterators = iterators;
     return this;
   }
@@ -610,22 +580,22 @@
     return (this.authorizations == null) ? 0 : this.authorizations.size();
   }
 
-  public java.util.Iterator<ByteBuffer> getAuthorizationsIterator() {
+  public java.util.Iterator<java.nio.ByteBuffer> getAuthorizationsIterator() {
     return (this.authorizations == null) ? null : this.authorizations.iterator();
   }
 
-  public void addToAuthorizations(ByteBuffer elem) {
+  public void addToAuthorizations(java.nio.ByteBuffer elem) {
     if (this.authorizations == null) {
-      this.authorizations = new ArrayList<ByteBuffer>();
+      this.authorizations = new java.util.ArrayList<java.nio.ByteBuffer>();
     }
     this.authorizations.add(elem);
   }
 
-  public List<ByteBuffer> getAuthorizations() {
+  public java.util.List<java.nio.ByteBuffer> getAuthorizations() {
     return this.authorizations;
   }
 
-  public ActiveScan setAuthorizations(List<ByteBuffer> authorizations) {
+  public ActiveScan setAuthorizations(java.util.List<java.nio.ByteBuffer> authorizations) {
     this.authorizations = authorizations;
     return this;
   }
@@ -645,13 +615,13 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case CLIENT:
       if (value == null) {
         unsetClient();
       } else {
-        setClient((String)value);
+        setClient((java.lang.String)value);
       }
       break;
 
@@ -659,7 +629,7 @@
       if (value == null) {
         unsetUser();
       } else {
-        setUser((String)value);
+        setUser((java.lang.String)value);
       }
       break;
 
@@ -667,7 +637,7 @@
       if (value == null) {
         unsetTable();
       } else {
-        setTable((String)value);
+        setTable((java.lang.String)value);
       }
       break;
 
@@ -675,7 +645,7 @@
       if (value == null) {
         unsetAge();
       } else {
-        setAge((Long)value);
+        setAge((java.lang.Long)value);
       }
       break;
 
@@ -683,7 +653,7 @@
       if (value == null) {
         unsetIdleTime();
       } else {
-        setIdleTime((Long)value);
+        setIdleTime((java.lang.Long)value);
       }
       break;
 
@@ -715,7 +685,7 @@
       if (value == null) {
         unsetColumns();
       } else {
-        setColumns((List<Column>)value);
+        setColumns((java.util.List<Column>)value);
       }
       break;
 
@@ -723,7 +693,7 @@
       if (value == null) {
         unsetIterators();
       } else {
-        setIterators((List<IteratorSetting>)value);
+        setIterators((java.util.List<IteratorSetting>)value);
       }
       break;
 
@@ -731,14 +701,14 @@
       if (value == null) {
         unsetAuthorizations();
       } else {
-        setAuthorizations((List<ByteBuffer>)value);
+        setAuthorizations((java.util.List<java.nio.ByteBuffer>)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case CLIENT:
       return getClient();
@@ -774,13 +744,13 @@
       return getAuthorizations();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -807,11 +777,11 @@
     case AUTHORIZATIONS:
       return isSetAuthorizations();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof ActiveScan)
@@ -822,6 +792,8 @@
   public boolean equals(ActiveScan that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_client = true && this.isSetClient();
     boolean that_present_client = true && that.isSetClient();
@@ -927,64 +899,49 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_client = true && (isSetClient());
-    list.add(present_client);
-    if (present_client)
-      list.add(client);
+    hashCode = hashCode * 8191 + ((isSetClient()) ? 131071 : 524287);
+    if (isSetClient())
+      hashCode = hashCode * 8191 + client.hashCode();
 
-    boolean present_user = true && (isSetUser());
-    list.add(present_user);
-    if (present_user)
-      list.add(user);
+    hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
+    if (isSetUser())
+      hashCode = hashCode * 8191 + user.hashCode();
 
-    boolean present_table = true && (isSetTable());
-    list.add(present_table);
-    if (present_table)
-      list.add(table);
+    hashCode = hashCode * 8191 + ((isSetTable()) ? 131071 : 524287);
+    if (isSetTable())
+      hashCode = hashCode * 8191 + table.hashCode();
 
-    boolean present_age = true;
-    list.add(present_age);
-    if (present_age)
-      list.add(age);
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(age);
 
-    boolean present_idleTime = true;
-    list.add(present_idleTime);
-    if (present_idleTime)
-      list.add(idleTime);
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(idleTime);
 
-    boolean present_type = true && (isSetType());
-    list.add(present_type);
-    if (present_type)
-      list.add(type.getValue());
+    hashCode = hashCode * 8191 + ((isSetType()) ? 131071 : 524287);
+    if (isSetType())
+      hashCode = hashCode * 8191 + type.getValue();
 
-    boolean present_state = true && (isSetState());
-    list.add(present_state);
-    if (present_state)
-      list.add(state.getValue());
+    hashCode = hashCode * 8191 + ((isSetState()) ? 131071 : 524287);
+    if (isSetState())
+      hashCode = hashCode * 8191 + state.getValue();
 
-    boolean present_extent = true && (isSetExtent());
-    list.add(present_extent);
-    if (present_extent)
-      list.add(extent);
+    hashCode = hashCode * 8191 + ((isSetExtent()) ? 131071 : 524287);
+    if (isSetExtent())
+      hashCode = hashCode * 8191 + extent.hashCode();
 
-    boolean present_columns = true && (isSetColumns());
-    list.add(present_columns);
-    if (present_columns)
-      list.add(columns);
+    hashCode = hashCode * 8191 + ((isSetColumns()) ? 131071 : 524287);
+    if (isSetColumns())
+      hashCode = hashCode * 8191 + columns.hashCode();
 
-    boolean present_iterators = true && (isSetIterators());
-    list.add(present_iterators);
-    if (present_iterators)
-      list.add(iterators);
+    hashCode = hashCode * 8191 + ((isSetIterators()) ? 131071 : 524287);
+    if (isSetIterators())
+      hashCode = hashCode * 8191 + iterators.hashCode();
 
-    boolean present_authorizations = true && (isSetAuthorizations());
-    list.add(present_authorizations);
-    if (present_authorizations)
-      list.add(authorizations);
+    hashCode = hashCode * 8191 + ((isSetAuthorizations()) ? 131071 : 524287);
+    if (isSetAuthorizations())
+      hashCode = hashCode * 8191 + authorizations.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -995,7 +952,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetClient()).compareTo(other.isSetClient());
+    lastComparison = java.lang.Boolean.valueOf(isSetClient()).compareTo(other.isSetClient());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1005,7 +962,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
+    lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1015,7 +972,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
+    lastComparison = java.lang.Boolean.valueOf(isSetTable()).compareTo(other.isSetTable());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1025,7 +982,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetAge()).compareTo(other.isSetAge());
+    lastComparison = java.lang.Boolean.valueOf(isSetAge()).compareTo(other.isSetAge());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1035,7 +992,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetIdleTime()).compareTo(other.isSetIdleTime());
+    lastComparison = java.lang.Boolean.valueOf(isSetIdleTime()).compareTo(other.isSetIdleTime());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1045,7 +1002,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType());
+    lastComparison = java.lang.Boolean.valueOf(isSetType()).compareTo(other.isSetType());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1055,7 +1012,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetState()).compareTo(other.isSetState());
+    lastComparison = java.lang.Boolean.valueOf(isSetState()).compareTo(other.isSetState());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1065,7 +1022,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetExtent()).compareTo(other.isSetExtent());
+    lastComparison = java.lang.Boolean.valueOf(isSetExtent()).compareTo(other.isSetExtent());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1075,7 +1032,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColumns()).compareTo(other.isSetColumns());
+    lastComparison = java.lang.Boolean.valueOf(isSetColumns()).compareTo(other.isSetColumns());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1085,7 +1042,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
+    lastComparison = java.lang.Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1095,7 +1052,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
+    lastComparison = java.lang.Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -1113,16 +1070,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("ActiveScan(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("ActiveScan(");
     boolean first = true;
 
     sb.append("client:");
@@ -1224,7 +1181,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -1234,13 +1191,13 @@
     }
   }
 
-  private static class ActiveScanStandardSchemeFactory implements SchemeFactory {
+  private static class ActiveScanStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ActiveScanStandardScheme getScheme() {
       return new ActiveScanStandardScheme();
     }
   }
 
-  private static class ActiveScanStandardScheme extends StandardScheme<ActiveScan> {
+  private static class ActiveScanStandardScheme extends org.apache.thrift.scheme.StandardScheme<ActiveScan> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, ActiveScan struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -1321,7 +1278,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list114 = iprot.readListBegin();
-                struct.columns = new ArrayList<Column>(_list114.size);
+                struct.columns = new java.util.ArrayList<Column>(_list114.size);
                 Column _elem115;
                 for (int _i116 = 0; _i116 < _list114.size; ++_i116)
                 {
@@ -1340,7 +1297,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list117 = iprot.readListBegin();
-                struct.iterators = new ArrayList<IteratorSetting>(_list117.size);
+                struct.iterators = new java.util.ArrayList<IteratorSetting>(_list117.size);
                 IteratorSetting _elem118;
                 for (int _i119 = 0; _i119 < _list117.size; ++_i119)
                 {
@@ -1359,8 +1316,8 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list120 = iprot.readListBegin();
-                struct.authorizations = new ArrayList<ByteBuffer>(_list120.size);
-                ByteBuffer _elem121;
+                struct.authorizations = new java.util.ArrayList<java.nio.ByteBuffer>(_list120.size);
+                java.nio.ByteBuffer _elem121;
                 for (int _i122 = 0; _i122 < _list120.size; ++_i122)
                 {
                   _elem121 = iprot.readBinary();
@@ -1452,7 +1409,7 @@
         oprot.writeFieldBegin(AUTHORIZATIONS_FIELD_DESC);
         {
           oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.authorizations.size()));
-          for (ByteBuffer _iter125 : struct.authorizations)
+          for (java.nio.ByteBuffer _iter125 : struct.authorizations)
           {
             oprot.writeBinary(_iter125);
           }
@@ -1466,18 +1423,18 @@
 
   }
 
-  private static class ActiveScanTupleSchemeFactory implements SchemeFactory {
+  private static class ActiveScanTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ActiveScanTupleScheme getScheme() {
       return new ActiveScanTupleScheme();
     }
   }
 
-  private static class ActiveScanTupleScheme extends TupleScheme<ActiveScan> {
+  private static class ActiveScanTupleScheme extends org.apache.thrift.scheme.TupleScheme<ActiveScan> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, ActiveScan struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetClient()) {
         optionals.set(0);
       }
@@ -1557,7 +1514,7 @@
       if (struct.isSetAuthorizations()) {
         {
           oprot.writeI32(struct.authorizations.size());
-          for (ByteBuffer _iter128 : struct.authorizations)
+          for (java.nio.ByteBuffer _iter128 : struct.authorizations)
           {
             oprot.writeBinary(_iter128);
           }
@@ -1567,8 +1524,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, ActiveScan struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(11);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(11);
       if (incoming.get(0)) {
         struct.client = iprot.readString();
         struct.setClientIsSet(true);
@@ -1605,7 +1562,7 @@
       if (incoming.get(8)) {
         {
           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);
+          struct.columns = new java.util.ArrayList<Column>(_list129.size);
           Column _elem130;
           for (int _i131 = 0; _i131 < _list129.size; ++_i131)
           {
@@ -1619,7 +1576,7 @@
       if (incoming.get(9)) {
         {
           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);
+          struct.iterators = new java.util.ArrayList<IteratorSetting>(_list132.size);
           IteratorSetting _elem133;
           for (int _i134 = 0; _i134 < _list132.size; ++_i134)
           {
@@ -1633,8 +1590,8 @@
       if (incoming.get(10)) {
         {
           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);
-          ByteBuffer _elem136;
+          struct.authorizations = new java.util.ArrayList<java.nio.ByteBuffer>(_list135.size);
+          java.nio.ByteBuffer _elem136;
           for (int _i137 = 0; _i137 < _list135.size; ++_i137)
           {
             _elem136 = iprot.readBinary();
@@ -1646,5 +1603,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 777e075..8b9e20f 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/BatchScanOptions.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/BatchScanOptions.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -60,16 +33,13 @@
   private static final org.apache.thrift.protocol.TField ITERATORS_FIELD_DESC = new org.apache.thrift.protocol.TField("iterators", org.apache.thrift.protocol.TType.LIST, (short)4);
   private static final org.apache.thrift.protocol.TField THREADS_FIELD_DESC = new org.apache.thrift.protocol.TField("threads", org.apache.thrift.protocol.TType.I32, (short)5);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new BatchScanOptionsStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new BatchScanOptionsTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new BatchScanOptionsStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new BatchScanOptionsTupleSchemeFactory();
 
-  public Set<ByteBuffer> authorizations; // optional
-  public List<Range> ranges; // optional
-  public List<ScanColumn> columns; // optional
-  public List<IteratorSetting> iterators; // optional
+  public java.util.Set<java.nio.ByteBuffer> authorizations; // optional
+  public java.util.List<Range> ranges; // optional
+  public java.util.List<ScanColumn> columns; // optional
+  public java.util.List<IteratorSetting> iterators; // optional
   public int threads; // optional
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -80,10 +50,10 @@
     ITERATORS((short)4, "iterators"),
     THREADS((short)5, "threads");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -114,21 +84,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -137,7 +107,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -146,9 +116,9 @@
   private static final int __THREADS_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
   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;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.AUTHORIZATIONS, new org.apache.thrift.meta_data.FieldMetaData("authorizations", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
             new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING            , true))));
@@ -163,7 +133,7 @@
             new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class))));
     tmpMap.put(_Fields.THREADS, new org.apache.thrift.meta_data.FieldMetaData("threads", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(BatchScanOptions.class, metaDataMap);
   }
 
@@ -176,25 +146,25 @@
   public BatchScanOptions(BatchScanOptions other) {
     __isset_bitfield = other.__isset_bitfield;
     if (other.isSetAuthorizations()) {
-      Set<ByteBuffer> __this__authorizations = new HashSet<ByteBuffer>(other.authorizations);
+      java.util.Set<java.nio.ByteBuffer> __this__authorizations = new java.util.HashSet<java.nio.ByteBuffer>(other.authorizations);
       this.authorizations = __this__authorizations;
     }
     if (other.isSetRanges()) {
-      List<Range> __this__ranges = new ArrayList<Range>(other.ranges.size());
+      java.util.List<Range> __this__ranges = new java.util.ArrayList<Range>(other.ranges.size());
       for (Range other_element : other.ranges) {
         __this__ranges.add(new Range(other_element));
       }
       this.ranges = __this__ranges;
     }
     if (other.isSetColumns()) {
-      List<ScanColumn> __this__columns = new ArrayList<ScanColumn>(other.columns.size());
+      java.util.List<ScanColumn> __this__columns = new java.util.ArrayList<ScanColumn>(other.columns.size());
       for (ScanColumn other_element : other.columns) {
         __this__columns.add(new ScanColumn(other_element));
       }
       this.columns = __this__columns;
     }
     if (other.isSetIterators()) {
-      List<IteratorSetting> __this__iterators = new ArrayList<IteratorSetting>(other.iterators.size());
+      java.util.List<IteratorSetting> __this__iterators = new java.util.ArrayList<IteratorSetting>(other.iterators.size());
       for (IteratorSetting other_element : other.iterators) {
         __this__iterators.add(new IteratorSetting(other_element));
       }
@@ -221,22 +191,22 @@
     return (this.authorizations == null) ? 0 : this.authorizations.size();
   }
 
-  public java.util.Iterator<ByteBuffer> getAuthorizationsIterator() {
+  public java.util.Iterator<java.nio.ByteBuffer> getAuthorizationsIterator() {
     return (this.authorizations == null) ? null : this.authorizations.iterator();
   }
 
-  public void addToAuthorizations(ByteBuffer elem) {
+  public void addToAuthorizations(java.nio.ByteBuffer elem) {
     if (this.authorizations == null) {
-      this.authorizations = new HashSet<ByteBuffer>();
+      this.authorizations = new java.util.HashSet<java.nio.ByteBuffer>();
     }
     this.authorizations.add(elem);
   }
 
-  public Set<ByteBuffer> getAuthorizations() {
+  public java.util.Set<java.nio.ByteBuffer> getAuthorizations() {
     return this.authorizations;
   }
 
-  public BatchScanOptions setAuthorizations(Set<ByteBuffer> authorizations) {
+  public BatchScanOptions setAuthorizations(java.util.Set<java.nio.ByteBuffer> authorizations) {
     this.authorizations = authorizations;
     return this;
   }
@@ -266,16 +236,16 @@
 
   public void addToRanges(Range elem) {
     if (this.ranges == null) {
-      this.ranges = new ArrayList<Range>();
+      this.ranges = new java.util.ArrayList<Range>();
     }
     this.ranges.add(elem);
   }
 
-  public List<Range> getRanges() {
+  public java.util.List<Range> getRanges() {
     return this.ranges;
   }
 
-  public BatchScanOptions setRanges(List<Range> ranges) {
+  public BatchScanOptions setRanges(java.util.List<Range> ranges) {
     this.ranges = ranges;
     return this;
   }
@@ -305,16 +275,16 @@
 
   public void addToColumns(ScanColumn elem) {
     if (this.columns == null) {
-      this.columns = new ArrayList<ScanColumn>();
+      this.columns = new java.util.ArrayList<ScanColumn>();
     }
     this.columns.add(elem);
   }
 
-  public List<ScanColumn> getColumns() {
+  public java.util.List<ScanColumn> getColumns() {
     return this.columns;
   }
 
-  public BatchScanOptions setColumns(List<ScanColumn> columns) {
+  public BatchScanOptions setColumns(java.util.List<ScanColumn> columns) {
     this.columns = columns;
     return this;
   }
@@ -344,16 +314,16 @@
 
   public void addToIterators(IteratorSetting elem) {
     if (this.iterators == null) {
-      this.iterators = new ArrayList<IteratorSetting>();
+      this.iterators = new java.util.ArrayList<IteratorSetting>();
     }
     this.iterators.add(elem);
   }
 
-  public List<IteratorSetting> getIterators() {
+  public java.util.List<IteratorSetting> getIterators() {
     return this.iterators;
   }
 
-  public BatchScanOptions setIterators(List<IteratorSetting> iterators) {
+  public BatchScanOptions setIterators(java.util.List<IteratorSetting> iterators) {
     this.iterators = iterators;
     return this;
   }
@@ -384,25 +354,25 @@
   }
 
   public void unsetThreads() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __THREADS_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __THREADS_ISSET_ID);
   }
 
   /** Returns true if field threads is set (has been assigned a value) and false otherwise */
   public boolean isSetThreads() {
-    return EncodingUtils.testBit(__isset_bitfield, __THREADS_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __THREADS_ISSET_ID);
   }
 
   public void setThreadsIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __THREADS_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __THREADS_ISSET_ID, value);
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case AUTHORIZATIONS:
       if (value == null) {
         unsetAuthorizations();
       } else {
-        setAuthorizations((Set<ByteBuffer>)value);
+        setAuthorizations((java.util.Set<java.nio.ByteBuffer>)value);
       }
       break;
 
@@ -410,7 +380,7 @@
       if (value == null) {
         unsetRanges();
       } else {
-        setRanges((List<Range>)value);
+        setRanges((java.util.List<Range>)value);
       }
       break;
 
@@ -418,7 +388,7 @@
       if (value == null) {
         unsetColumns();
       } else {
-        setColumns((List<ScanColumn>)value);
+        setColumns((java.util.List<ScanColumn>)value);
       }
       break;
 
@@ -426,7 +396,7 @@
       if (value == null) {
         unsetIterators();
       } else {
-        setIterators((List<IteratorSetting>)value);
+        setIterators((java.util.List<IteratorSetting>)value);
       }
       break;
 
@@ -434,14 +404,14 @@
       if (value == null) {
         unsetThreads();
       } else {
-        setThreads((Integer)value);
+        setThreads((java.lang.Integer)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case AUTHORIZATIONS:
       return getAuthorizations();
@@ -459,13 +429,13 @@
       return getThreads();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -480,11 +450,11 @@
     case THREADS:
       return isSetThreads();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof BatchScanOptions)
@@ -495,6 +465,8 @@
   public boolean equals(BatchScanOptions that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_authorizations = true && this.isSetAuthorizations();
     boolean that_present_authorizations = true && that.isSetAuthorizations();
@@ -546,34 +518,29 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_authorizations = true && (isSetAuthorizations());
-    list.add(present_authorizations);
-    if (present_authorizations)
-      list.add(authorizations);
+    hashCode = hashCode * 8191 + ((isSetAuthorizations()) ? 131071 : 524287);
+    if (isSetAuthorizations())
+      hashCode = hashCode * 8191 + authorizations.hashCode();
 
-    boolean present_ranges = true && (isSetRanges());
-    list.add(present_ranges);
-    if (present_ranges)
-      list.add(ranges);
+    hashCode = hashCode * 8191 + ((isSetRanges()) ? 131071 : 524287);
+    if (isSetRanges())
+      hashCode = hashCode * 8191 + ranges.hashCode();
 
-    boolean present_columns = true && (isSetColumns());
-    list.add(present_columns);
-    if (present_columns)
-      list.add(columns);
+    hashCode = hashCode * 8191 + ((isSetColumns()) ? 131071 : 524287);
+    if (isSetColumns())
+      hashCode = hashCode * 8191 + columns.hashCode();
 
-    boolean present_iterators = true && (isSetIterators());
-    list.add(present_iterators);
-    if (present_iterators)
-      list.add(iterators);
+    hashCode = hashCode * 8191 + ((isSetIterators()) ? 131071 : 524287);
+    if (isSetIterators())
+      hashCode = hashCode * 8191 + iterators.hashCode();
 
-    boolean present_threads = true && (isSetThreads());
-    list.add(present_threads);
-    if (present_threads)
-      list.add(threads);
+    hashCode = hashCode * 8191 + ((isSetThreads()) ? 131071 : 524287);
+    if (isSetThreads())
+      hashCode = hashCode * 8191 + threads;
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -584,7 +551,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
+    lastComparison = java.lang.Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -594,7 +561,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetRanges()).compareTo(other.isSetRanges());
+    lastComparison = java.lang.Boolean.valueOf(isSetRanges()).compareTo(other.isSetRanges());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -604,7 +571,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColumns()).compareTo(other.isSetColumns());
+    lastComparison = java.lang.Boolean.valueOf(isSetColumns()).compareTo(other.isSetColumns());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -614,7 +581,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
+    lastComparison = java.lang.Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -624,7 +591,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetThreads()).compareTo(other.isSetThreads());
+    lastComparison = java.lang.Boolean.valueOf(isSetThreads()).compareTo(other.isSetThreads());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -642,16 +609,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("BatchScanOptions(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("BatchScanOptions(");
     boolean first = true;
 
     if (isSetAuthorizations()) {
@@ -716,7 +683,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -726,13 +693,13 @@
     }
   }
 
-  private static class BatchScanOptionsStandardSchemeFactory implements SchemeFactory {
+  private static class BatchScanOptionsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public BatchScanOptionsStandardScheme getScheme() {
       return new BatchScanOptionsStandardScheme();
     }
   }
 
-  private static class BatchScanOptionsStandardScheme extends StandardScheme<BatchScanOptions> {
+  private static class BatchScanOptionsStandardScheme extends org.apache.thrift.scheme.StandardScheme<BatchScanOptions> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, BatchScanOptions struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -748,8 +715,8 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
               {
                 org.apache.thrift.protocol.TSet _set50 = iprot.readSetBegin();
-                struct.authorizations = new HashSet<ByteBuffer>(2*_set50.size);
-                ByteBuffer _elem51;
+                struct.authorizations = new java.util.HashSet<java.nio.ByteBuffer>(2*_set50.size);
+                java.nio.ByteBuffer _elem51;
                 for (int _i52 = 0; _i52 < _set50.size; ++_i52)
                 {
                   _elem51 = iprot.readBinary();
@@ -766,7 +733,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list53 = iprot.readListBegin();
-                struct.ranges = new ArrayList<Range>(_list53.size);
+                struct.ranges = new java.util.ArrayList<Range>(_list53.size);
                 Range _elem54;
                 for (int _i55 = 0; _i55 < _list53.size; ++_i55)
                 {
@@ -785,7 +752,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list56 = iprot.readListBegin();
-                struct.columns = new ArrayList<ScanColumn>(_list56.size);
+                struct.columns = new java.util.ArrayList<ScanColumn>(_list56.size);
                 ScanColumn _elem57;
                 for (int _i58 = 0; _i58 < _list56.size; ++_i58)
                 {
@@ -804,7 +771,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list59 = iprot.readListBegin();
-                struct.iterators = new ArrayList<IteratorSetting>(_list59.size);
+                struct.iterators = new java.util.ArrayList<IteratorSetting>(_list59.size);
                 IteratorSetting _elem60;
                 for (int _i61 = 0; _i61 < _list59.size; ++_i61)
                 {
@@ -847,7 +814,7 @@
           oprot.writeFieldBegin(AUTHORIZATIONS_FIELD_DESC);
           {
             oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.authorizations.size()));
-            for (ByteBuffer _iter62 : struct.authorizations)
+            for (java.nio.ByteBuffer _iter62 : struct.authorizations)
             {
               oprot.writeBinary(_iter62);
             }
@@ -909,18 +876,18 @@
 
   }
 
-  private static class BatchScanOptionsTupleSchemeFactory implements SchemeFactory {
+  private static class BatchScanOptionsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public BatchScanOptionsTupleScheme getScheme() {
       return new BatchScanOptionsTupleScheme();
     }
   }
 
-  private static class BatchScanOptionsTupleScheme extends TupleScheme<BatchScanOptions> {
+  private static class BatchScanOptionsTupleScheme extends org.apache.thrift.scheme.TupleScheme<BatchScanOptions> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, BatchScanOptions struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetAuthorizations()) {
         optionals.set(0);
       }
@@ -940,7 +907,7 @@
       if (struct.isSetAuthorizations()) {
         {
           oprot.writeI32(struct.authorizations.size());
-          for (ByteBuffer _iter66 : struct.authorizations)
+          for (java.nio.ByteBuffer _iter66 : struct.authorizations)
           {
             oprot.writeBinary(_iter66);
           }
@@ -980,13 +947,13 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, BatchScanOptions struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(5);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(5);
       if (incoming.get(0)) {
         {
           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);
-          ByteBuffer _elem71;
+          struct.authorizations = new java.util.HashSet<java.nio.ByteBuffer>(2*_set70.size);
+          java.nio.ByteBuffer _elem71;
           for (int _i72 = 0; _i72 < _set70.size; ++_i72)
           {
             _elem71 = iprot.readBinary();
@@ -998,7 +965,7 @@
       if (incoming.get(1)) {
         {
           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);
+          struct.ranges = new java.util.ArrayList<Range>(_list73.size);
           Range _elem74;
           for (int _i75 = 0; _i75 < _list73.size; ++_i75)
           {
@@ -1012,7 +979,7 @@
       if (incoming.get(2)) {
         {
           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);
+          struct.columns = new java.util.ArrayList<ScanColumn>(_list76.size);
           ScanColumn _elem77;
           for (int _i78 = 0; _i78 < _list76.size; ++_i78)
           {
@@ -1026,7 +993,7 @@
       if (incoming.get(3)) {
         {
           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);
+          struct.iterators = new java.util.ArrayList<IteratorSetting>(_list79.size);
           IteratorSetting _elem80;
           for (int _i81 = 0; _i81 < _list79.size; ++_i81)
           {
@@ -1044,5 +1011,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 96ae162..7220637 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/Column.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/Column.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -58,15 +31,12 @@
   private static final org.apache.thrift.protocol.TField COL_QUALIFIER_FIELD_DESC = new org.apache.thrift.protocol.TField("colQualifier", org.apache.thrift.protocol.TType.STRING, (short)2);
   private static final org.apache.thrift.protocol.TField COL_VISIBILITY_FIELD_DESC = new org.apache.thrift.protocol.TField("colVisibility", 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 ColumnStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new ColumnTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ColumnStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ColumnTupleSchemeFactory();
 
-  public ByteBuffer colFamily; // required
-  public ByteBuffer colQualifier; // required
-  public ByteBuffer colVisibility; // required
+  public java.nio.ByteBuffer colFamily; // required
+  public java.nio.ByteBuffer colQualifier; // required
+  public java.nio.ByteBuffer colVisibility; // 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 {
@@ -74,10 +44,10 @@
     COL_QUALIFIER((short)2, "colQualifier"),
     COL_VISIBILITY((short)3, "colVisibility");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -104,21 +74,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -127,22 +97,22 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.COL_FAMILY, new org.apache.thrift.meta_data.FieldMetaData("colFamily", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
     tmpMap.put(_Fields.COL_QUALIFIER, new org.apache.thrift.meta_data.FieldMetaData("colQualifier", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
     tmpMap.put(_Fields.COL_VISIBILITY, new org.apache.thrift.meta_data.FieldMetaData("colVisibility", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Column.class, metaDataMap);
   }
 
@@ -150,9 +120,9 @@
   }
 
   public Column(
-    ByteBuffer colFamily,
-    ByteBuffer colQualifier,
-    ByteBuffer colVisibility)
+    java.nio.ByteBuffer colFamily,
+    java.nio.ByteBuffer colQualifier,
+    java.nio.ByteBuffer colVisibility)
   {
     this();
     this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
@@ -191,16 +161,16 @@
     return colFamily == null ? null : colFamily.array();
   }
 
-  public ByteBuffer bufferForColFamily() {
+  public java.nio.ByteBuffer bufferForColFamily() {
     return org.apache.thrift.TBaseHelper.copyBinary(colFamily);
   }
 
   public Column setColFamily(byte[] colFamily) {
-    this.colFamily = colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colFamily, colFamily.length));
+    this.colFamily = colFamily == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colFamily.clone());
     return this;
   }
 
-  public Column setColFamily(ByteBuffer colFamily) {
+  public Column setColFamily(java.nio.ByteBuffer colFamily) {
     this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
     return this;
   }
@@ -225,16 +195,16 @@
     return colQualifier == null ? null : colQualifier.array();
   }
 
-  public ByteBuffer bufferForColQualifier() {
+  public java.nio.ByteBuffer bufferForColQualifier() {
     return org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
   }
 
   public Column setColQualifier(byte[] colQualifier) {
-    this.colQualifier = colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colQualifier, colQualifier.length));
+    this.colQualifier = colQualifier == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colQualifier.clone());
     return this;
   }
 
-  public Column setColQualifier(ByteBuffer colQualifier) {
+  public Column setColQualifier(java.nio.ByteBuffer colQualifier) {
     this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
     return this;
   }
@@ -259,16 +229,16 @@
     return colVisibility == null ? null : colVisibility.array();
   }
 
-  public ByteBuffer bufferForColVisibility() {
+  public java.nio.ByteBuffer bufferForColVisibility() {
     return org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
   }
 
   public Column setColVisibility(byte[] colVisibility) {
-    this.colVisibility = colVisibility == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colVisibility, colVisibility.length));
+    this.colVisibility = colVisibility == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colVisibility.clone());
     return this;
   }
 
-  public Column setColVisibility(ByteBuffer colVisibility) {
+  public Column setColVisibility(java.nio.ByteBuffer colVisibility) {
     this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
     return this;
   }
@@ -288,13 +258,17 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case COL_FAMILY:
       if (value == null) {
         unsetColFamily();
       } else {
-        setColFamily((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColFamily((byte[])value);
+        } else {
+          setColFamily((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -302,7 +276,11 @@
       if (value == null) {
         unsetColQualifier();
       } else {
-        setColQualifier((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColQualifier((byte[])value);
+        } else {
+          setColQualifier((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -310,14 +288,18 @@
       if (value == null) {
         unsetColVisibility();
       } else {
-        setColVisibility((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColVisibility((byte[])value);
+        } else {
+          setColVisibility((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case COL_FAMILY:
       return getColFamily();
@@ -329,13 +311,13 @@
       return getColVisibility();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -346,11 +328,11 @@
     case COL_VISIBILITY:
       return isSetColVisibility();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof Column)
@@ -361,6 +343,8 @@
   public boolean equals(Column that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_colFamily = true && this.isSetColFamily();
     boolean that_present_colFamily = true && that.isSetColFamily();
@@ -394,24 +378,21 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_colFamily = true && (isSetColFamily());
-    list.add(present_colFamily);
-    if (present_colFamily)
-      list.add(colFamily);
+    hashCode = hashCode * 8191 + ((isSetColFamily()) ? 131071 : 524287);
+    if (isSetColFamily())
+      hashCode = hashCode * 8191 + colFamily.hashCode();
 
-    boolean present_colQualifier = true && (isSetColQualifier());
-    list.add(present_colQualifier);
-    if (present_colQualifier)
-      list.add(colQualifier);
+    hashCode = hashCode * 8191 + ((isSetColQualifier()) ? 131071 : 524287);
+    if (isSetColQualifier())
+      hashCode = hashCode * 8191 + colQualifier.hashCode();
 
-    boolean present_colVisibility = true && (isSetColVisibility());
-    list.add(present_colVisibility);
-    if (present_colVisibility)
-      list.add(colVisibility);
+    hashCode = hashCode * 8191 + ((isSetColVisibility()) ? 131071 : 524287);
+    if (isSetColVisibility())
+      hashCode = hashCode * 8191 + colVisibility.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -422,7 +403,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetColFamily()).compareTo(other.isSetColFamily());
+    lastComparison = java.lang.Boolean.valueOf(isSetColFamily()).compareTo(other.isSetColFamily());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -432,7 +413,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColQualifier()).compareTo(other.isSetColQualifier());
+    lastComparison = java.lang.Boolean.valueOf(isSetColQualifier()).compareTo(other.isSetColQualifier());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -442,7 +423,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColVisibility()).compareTo(other.isSetColVisibility());
+    lastComparison = java.lang.Boolean.valueOf(isSetColVisibility()).compareTo(other.isSetColVisibility());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -460,16 +441,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("Column(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("Column(");
     boolean first = true;
 
     sb.append("colFamily:");
@@ -512,7 +493,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -520,13 +501,13 @@
     }
   }
 
-  private static class ColumnStandardSchemeFactory implements SchemeFactory {
+  private static class ColumnStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ColumnStandardScheme getScheme() {
       return new ColumnStandardScheme();
     }
   }
 
-  private static class ColumnStandardScheme extends StandardScheme<Column> {
+  private static class ColumnStandardScheme extends org.apache.thrift.scheme.StandardScheme<Column> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, Column struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -598,18 +579,18 @@
 
   }
 
-  private static class ColumnTupleSchemeFactory implements SchemeFactory {
+  private static class ColumnTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ColumnTupleScheme getScheme() {
       return new ColumnTupleScheme();
     }
   }
 
-  private static class ColumnTupleScheme extends TupleScheme<Column> {
+  private static class ColumnTupleScheme extends org.apache.thrift.scheme.TupleScheme<Column> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, Column struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetColFamily()) {
         optionals.set(0);
       }
@@ -633,8 +614,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, Column struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(3);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(3);
       if (incoming.get(0)) {
         struct.colFamily = iprot.readBinary();
         struct.setColFamilyIsSet(true);
@@ -650,5 +631,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 33dfdbe..f655f46 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ColumnUpdate.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ColumnUpdate.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -61,17 +34,14 @@
   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)5);
   private static final org.apache.thrift.protocol.TField DELETE_CELL_FIELD_DESC = new org.apache.thrift.protocol.TField("deleteCell", org.apache.thrift.protocol.TType.BOOL, (short)6);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new ColumnUpdateStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new ColumnUpdateTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ColumnUpdateStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ColumnUpdateTupleSchemeFactory();
 
-  public ByteBuffer colFamily; // required
-  public ByteBuffer colQualifier; // required
-  public ByteBuffer colVisibility; // optional
+  public java.nio.ByteBuffer colFamily; // required
+  public java.nio.ByteBuffer colQualifier; // required
+  public java.nio.ByteBuffer colVisibility; // optional
   public long timestamp; // optional
-  public ByteBuffer value; // optional
+  public java.nio.ByteBuffer value; // optional
   public boolean deleteCell; // optional
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -83,10 +53,10 @@
     VALUE((short)5, "value"),
     DELETE_CELL((short)6, "deleteCell");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -119,21 +89,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -142,7 +112,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -152,9 +122,9 @@
   private static final int __DELETECELL_ISSET_ID = 1;
   private byte __isset_bitfield = 0;
   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;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.COL_FAMILY, new org.apache.thrift.meta_data.FieldMetaData("colFamily", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
     tmpMap.put(_Fields.COL_QUALIFIER, new org.apache.thrift.meta_data.FieldMetaData("colQualifier", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -167,7 +137,7 @@
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
     tmpMap.put(_Fields.DELETE_CELL, new org.apache.thrift.meta_data.FieldMetaData("deleteCell", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ColumnUpdate.class, metaDataMap);
   }
 
@@ -175,8 +145,8 @@
   }
 
   public ColumnUpdate(
-    ByteBuffer colFamily,
-    ByteBuffer colQualifier)
+    java.nio.ByteBuffer colFamily,
+    java.nio.ByteBuffer colQualifier)
   {
     this();
     this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
@@ -225,16 +195,16 @@
     return colFamily == null ? null : colFamily.array();
   }
 
-  public ByteBuffer bufferForColFamily() {
+  public java.nio.ByteBuffer bufferForColFamily() {
     return org.apache.thrift.TBaseHelper.copyBinary(colFamily);
   }
 
   public ColumnUpdate setColFamily(byte[] colFamily) {
-    this.colFamily = colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colFamily, colFamily.length));
+    this.colFamily = colFamily == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colFamily.clone());
     return this;
   }
 
-  public ColumnUpdate setColFamily(ByteBuffer colFamily) {
+  public ColumnUpdate setColFamily(java.nio.ByteBuffer colFamily) {
     this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
     return this;
   }
@@ -259,16 +229,16 @@
     return colQualifier == null ? null : colQualifier.array();
   }
 
-  public ByteBuffer bufferForColQualifier() {
+  public java.nio.ByteBuffer bufferForColQualifier() {
     return org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
   }
 
   public ColumnUpdate setColQualifier(byte[] colQualifier) {
-    this.colQualifier = colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colQualifier, colQualifier.length));
+    this.colQualifier = colQualifier == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colQualifier.clone());
     return this;
   }
 
-  public ColumnUpdate setColQualifier(ByteBuffer colQualifier) {
+  public ColumnUpdate setColQualifier(java.nio.ByteBuffer colQualifier) {
     this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
     return this;
   }
@@ -293,16 +263,16 @@
     return colVisibility == null ? null : colVisibility.array();
   }
 
-  public ByteBuffer bufferForColVisibility() {
+  public java.nio.ByteBuffer bufferForColVisibility() {
     return org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
   }
 
   public ColumnUpdate setColVisibility(byte[] colVisibility) {
-    this.colVisibility = colVisibility == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colVisibility, colVisibility.length));
+    this.colVisibility = colVisibility == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colVisibility.clone());
     return this;
   }
 
-  public ColumnUpdate setColVisibility(ByteBuffer colVisibility) {
+  public ColumnUpdate setColVisibility(java.nio.ByteBuffer colVisibility) {
     this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
     return this;
   }
@@ -333,16 +303,16 @@
   }
 
   public void unsetTimestamp() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
   }
 
   /** Returns true if field timestamp is set (has been assigned a value) and false otherwise */
   public boolean isSetTimestamp() {
-    return EncodingUtils.testBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
   }
 
   public void setTimestampIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value);
   }
 
   public byte[] getValue() {
@@ -350,16 +320,16 @@
     return value == null ? null : value.array();
   }
 
-  public ByteBuffer bufferForValue() {
+  public java.nio.ByteBuffer bufferForValue() {
     return org.apache.thrift.TBaseHelper.copyBinary(value);
   }
 
   public ColumnUpdate setValue(byte[] value) {
-    this.value = value == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(value, value.length));
+    this.value = value == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(value.clone());
     return this;
   }
 
-  public ColumnUpdate setValue(ByteBuffer value) {
+  public ColumnUpdate setValue(java.nio.ByteBuffer value) {
     this.value = org.apache.thrift.TBaseHelper.copyBinary(value);
     return this;
   }
@@ -390,25 +360,29 @@
   }
 
   public void unsetDeleteCell() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __DELETECELL_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DELETECELL_ISSET_ID);
   }
 
   /** Returns true if field deleteCell is set (has been assigned a value) and false otherwise */
   public boolean isSetDeleteCell() {
-    return EncodingUtils.testBit(__isset_bitfield, __DELETECELL_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DELETECELL_ISSET_ID);
   }
 
   public void setDeleteCellIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __DELETECELL_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DELETECELL_ISSET_ID, value);
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case COL_FAMILY:
       if (value == null) {
         unsetColFamily();
       } else {
-        setColFamily((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColFamily((byte[])value);
+        } else {
+          setColFamily((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -416,7 +390,11 @@
       if (value == null) {
         unsetColQualifier();
       } else {
-        setColQualifier((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColQualifier((byte[])value);
+        } else {
+          setColQualifier((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -424,7 +402,11 @@
       if (value == null) {
         unsetColVisibility();
       } else {
-        setColVisibility((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColVisibility((byte[])value);
+        } else {
+          setColVisibility((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -432,7 +414,7 @@
       if (value == null) {
         unsetTimestamp();
       } else {
-        setTimestamp((Long)value);
+        setTimestamp((java.lang.Long)value);
       }
       break;
 
@@ -440,7 +422,11 @@
       if (value == null) {
         unsetValue();
       } else {
-        setValue((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setValue((byte[])value);
+        } else {
+          setValue((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -448,14 +434,14 @@
       if (value == null) {
         unsetDeleteCell();
       } else {
-        setDeleteCell((Boolean)value);
+        setDeleteCell((java.lang.Boolean)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case COL_FAMILY:
       return getColFamily();
@@ -476,13 +462,13 @@
       return isDeleteCell();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -499,11 +485,11 @@
     case DELETE_CELL:
       return isSetDeleteCell();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof ColumnUpdate)
@@ -514,6 +500,8 @@
   public boolean equals(ColumnUpdate that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_colFamily = true && this.isSetColFamily();
     boolean that_present_colFamily = true && that.isSetColFamily();
@@ -574,39 +562,33 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_colFamily = true && (isSetColFamily());
-    list.add(present_colFamily);
-    if (present_colFamily)
-      list.add(colFamily);
+    hashCode = hashCode * 8191 + ((isSetColFamily()) ? 131071 : 524287);
+    if (isSetColFamily())
+      hashCode = hashCode * 8191 + colFamily.hashCode();
 
-    boolean present_colQualifier = true && (isSetColQualifier());
-    list.add(present_colQualifier);
-    if (present_colQualifier)
-      list.add(colQualifier);
+    hashCode = hashCode * 8191 + ((isSetColQualifier()) ? 131071 : 524287);
+    if (isSetColQualifier())
+      hashCode = hashCode * 8191 + colQualifier.hashCode();
 
-    boolean present_colVisibility = true && (isSetColVisibility());
-    list.add(present_colVisibility);
-    if (present_colVisibility)
-      list.add(colVisibility);
+    hashCode = hashCode * 8191 + ((isSetColVisibility()) ? 131071 : 524287);
+    if (isSetColVisibility())
+      hashCode = hashCode * 8191 + colVisibility.hashCode();
 
-    boolean present_timestamp = true && (isSetTimestamp());
-    list.add(present_timestamp);
-    if (present_timestamp)
-      list.add(timestamp);
+    hashCode = hashCode * 8191 + ((isSetTimestamp()) ? 131071 : 524287);
+    if (isSetTimestamp())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(timestamp);
 
-    boolean present_value = true && (isSetValue());
-    list.add(present_value);
-    if (present_value)
-      list.add(value);
+    hashCode = hashCode * 8191 + ((isSetValue()) ? 131071 : 524287);
+    if (isSetValue())
+      hashCode = hashCode * 8191 + value.hashCode();
 
-    boolean present_deleteCell = true && (isSetDeleteCell());
-    list.add(present_deleteCell);
-    if (present_deleteCell)
-      list.add(deleteCell);
+    hashCode = hashCode * 8191 + ((isSetDeleteCell()) ? 131071 : 524287);
+    if (isSetDeleteCell())
+      hashCode = hashCode * 8191 + ((deleteCell) ? 131071 : 524287);
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -617,7 +599,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetColFamily()).compareTo(other.isSetColFamily());
+    lastComparison = java.lang.Boolean.valueOf(isSetColFamily()).compareTo(other.isSetColFamily());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -627,7 +609,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColQualifier()).compareTo(other.isSetColQualifier());
+    lastComparison = java.lang.Boolean.valueOf(isSetColQualifier()).compareTo(other.isSetColQualifier());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -637,7 +619,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColVisibility()).compareTo(other.isSetColVisibility());
+    lastComparison = java.lang.Boolean.valueOf(isSetColVisibility()).compareTo(other.isSetColVisibility());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -647,7 +629,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetTimestamp()).compareTo(other.isSetTimestamp());
+    lastComparison = java.lang.Boolean.valueOf(isSetTimestamp()).compareTo(other.isSetTimestamp());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -657,7 +639,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
+    lastComparison = java.lang.Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -667,7 +649,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetDeleteCell()).compareTo(other.isSetDeleteCell());
+    lastComparison = java.lang.Boolean.valueOf(isSetDeleteCell()).compareTo(other.isSetDeleteCell());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -685,16 +667,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("ColumnUpdate(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("ColumnUpdate(");
     boolean first = true;
 
     sb.append("colFamily:");
@@ -761,7 +743,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -771,13 +753,13 @@
     }
   }
 
-  private static class ColumnUpdateStandardSchemeFactory implements SchemeFactory {
+  private static class ColumnUpdateStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ColumnUpdateStandardScheme getScheme() {
       return new ColumnUpdateStandardScheme();
     }
   }
 
-  private static class ColumnUpdateStandardScheme extends StandardScheme<ColumnUpdate> {
+  private static class ColumnUpdateStandardScheme extends org.apache.thrift.scheme.StandardScheme<ColumnUpdate> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, ColumnUpdate struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -892,18 +874,18 @@
 
   }
 
-  private static class ColumnUpdateTupleSchemeFactory implements SchemeFactory {
+  private static class ColumnUpdateTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ColumnUpdateTupleScheme getScheme() {
       return new ColumnUpdateTupleScheme();
     }
   }
 
-  private static class ColumnUpdateTupleScheme extends TupleScheme<ColumnUpdate> {
+  private static class ColumnUpdateTupleScheme extends org.apache.thrift.scheme.TupleScheme<ColumnUpdate> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, ColumnUpdate struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetColFamily()) {
         optionals.set(0);
       }
@@ -945,8 +927,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, ColumnUpdate struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(6);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(6);
       if (incoming.get(0)) {
         struct.colFamily = iprot.readBinary();
         struct.setColFamilyIsSet(true);
@@ -974,5 +956,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 77cf53d..b4b3255 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum CompactionReason implements org.apache.thrift.TEnum {
+public enum CompactionReason implements org.apache.thrift.TEnum {
   USER(0),
   SYSTEM(1),
   CHOP(2),
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 e8f7f88..03c0688 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/CompactionStrategyConfig.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/CompactionStrategyConfig.java
@@ -15,66 +15,36 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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);
   private static final org.apache.thrift.protocol.TField OPTIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("options", org.apache.thrift.protocol.TType.MAP, (short)2);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new CompactionStrategyConfigStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new CompactionStrategyConfigTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new CompactionStrategyConfigStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new CompactionStrategyConfigTupleSchemeFactory();
 
-  public String className; // required
-  public Map<String,String> options; // required
+  public java.lang.String className; // required
+  public java.util.Map<java.lang.String,java.lang.String> options; // 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 {
     CLASS_NAME((short)1, "className"),
     OPTIONS((short)2, "options");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -99,21 +69,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -122,22 +92,22 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     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.OPTIONS, new org.apache.thrift.meta_data.FieldMetaData("options", 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))));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(CompactionStrategyConfig.class, metaDataMap);
   }
 
@@ -145,8 +115,8 @@
   }
 
   public CompactionStrategyConfig(
-    String className,
-    Map<String,String> options)
+    java.lang.String className,
+    java.util.Map<java.lang.String,java.lang.String> options)
   {
     this();
     this.className = className;
@@ -161,7 +131,7 @@
       this.className = other.className;
     }
     if (other.isSetOptions()) {
-      Map<String,String> __this__options = new HashMap<String,String>(other.options);
+      java.util.Map<java.lang.String,java.lang.String> __this__options = new java.util.HashMap<java.lang.String,java.lang.String>(other.options);
       this.options = __this__options;
     }
   }
@@ -176,11 +146,11 @@
     this.options = null;
   }
 
-  public String getClassName() {
+  public java.lang.String getClassName() {
     return this.className;
   }
 
-  public CompactionStrategyConfig setClassName(String className) {
+  public CompactionStrategyConfig setClassName(java.lang.String className) {
     this.className = className;
     return this;
   }
@@ -204,18 +174,18 @@
     return (this.options == null) ? 0 : this.options.size();
   }
 
-  public void putToOptions(String key, String val) {
+  public void putToOptions(java.lang.String key, java.lang.String val) {
     if (this.options == null) {
-      this.options = new HashMap<String,String>();
+      this.options = new java.util.HashMap<java.lang.String,java.lang.String>();
     }
     this.options.put(key, val);
   }
 
-  public Map<String,String> getOptions() {
+  public java.util.Map<java.lang.String,java.lang.String> getOptions() {
     return this.options;
   }
 
-  public CompactionStrategyConfig setOptions(Map<String,String> options) {
+  public CompactionStrategyConfig setOptions(java.util.Map<java.lang.String,java.lang.String> options) {
     this.options = options;
     return this;
   }
@@ -235,13 +205,13 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case CLASS_NAME:
       if (value == null) {
         unsetClassName();
       } else {
-        setClassName((String)value);
+        setClassName((java.lang.String)value);
       }
       break;
 
@@ -249,14 +219,14 @@
       if (value == null) {
         unsetOptions();
       } else {
-        setOptions((Map<String,String>)value);
+        setOptions((java.util.Map<java.lang.String,java.lang.String>)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case CLASS_NAME:
       return getClassName();
@@ -265,13 +235,13 @@
       return getOptions();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -280,11 +250,11 @@
     case OPTIONS:
       return isSetOptions();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof CompactionStrategyConfig)
@@ -295,6 +265,8 @@
   public boolean equals(CompactionStrategyConfig that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_className = true && this.isSetClassName();
     boolean that_present_className = true && that.isSetClassName();
@@ -319,19 +291,17 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_className = true && (isSetClassName());
-    list.add(present_className);
-    if (present_className)
-      list.add(className);
+    hashCode = hashCode * 8191 + ((isSetClassName()) ? 131071 : 524287);
+    if (isSetClassName())
+      hashCode = hashCode * 8191 + className.hashCode();
 
-    boolean present_options = true && (isSetOptions());
-    list.add(present_options);
-    if (present_options)
-      list.add(options);
+    hashCode = hashCode * 8191 + ((isSetOptions()) ? 131071 : 524287);
+    if (isSetOptions())
+      hashCode = hashCode * 8191 + options.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -342,7 +312,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
+    lastComparison = java.lang.Boolean.valueOf(isSetClassName()).compareTo(other.isSetClassName());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -352,7 +322,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
+    lastComparison = java.lang.Boolean.valueOf(isSetOptions()).compareTo(other.isSetOptions());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -370,16 +340,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("CompactionStrategyConfig(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("CompactionStrategyConfig(");
     boolean first = true;
 
     sb.append("className:");
@@ -414,7 +384,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -422,13 +392,13 @@
     }
   }
 
-  private static class CompactionStrategyConfigStandardSchemeFactory implements SchemeFactory {
+  private static class CompactionStrategyConfigStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public CompactionStrategyConfigStandardScheme getScheme() {
       return new CompactionStrategyConfigStandardScheme();
     }
   }
 
-  private static class CompactionStrategyConfigStandardScheme extends StandardScheme<CompactionStrategyConfig> {
+  private static class CompactionStrategyConfigStandardScheme extends org.apache.thrift.scheme.StandardScheme<CompactionStrategyConfig> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, CompactionStrategyConfig struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -452,9 +422,9 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
               {
                 org.apache.thrift.protocol.TMap _map154 = iprot.readMapBegin();
-                struct.options = new HashMap<String,String>(2*_map154.size);
-                String _key155;
-                String _val156;
+                struct.options = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map154.size);
+                java.lang.String _key155;
+                java.lang.String _val156;
                 for (int _i157 = 0; _i157 < _map154.size; ++_i157)
                 {
                   _key155 = iprot.readString();
@@ -492,7 +462,7 @@
         oprot.writeFieldBegin(OPTIONS_FIELD_DESC);
         {
           oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.options.size()));
-          for (Map.Entry<String, String> _iter158 : struct.options.entrySet())
+          for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter158 : struct.options.entrySet())
           {
             oprot.writeString(_iter158.getKey());
             oprot.writeString(_iter158.getValue());
@@ -507,18 +477,18 @@
 
   }
 
-  private static class CompactionStrategyConfigTupleSchemeFactory implements SchemeFactory {
+  private static class CompactionStrategyConfigTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public CompactionStrategyConfigTupleScheme getScheme() {
       return new CompactionStrategyConfigTupleScheme();
     }
   }
 
-  private static class CompactionStrategyConfigTupleScheme extends TupleScheme<CompactionStrategyConfig> {
+  private static class CompactionStrategyConfigTupleScheme extends org.apache.thrift.scheme.TupleScheme<CompactionStrategyConfig> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, CompactionStrategyConfig struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetClassName()) {
         optionals.set(0);
       }
@@ -532,7 +502,7 @@
       if (struct.isSetOptions()) {
         {
           oprot.writeI32(struct.options.size());
-          for (Map.Entry<String, String> _iter159 : struct.options.entrySet())
+          for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter159 : struct.options.entrySet())
           {
             oprot.writeString(_iter159.getKey());
             oprot.writeString(_iter159.getValue());
@@ -543,8 +513,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, CompactionStrategyConfig struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(2);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(2);
       if (incoming.get(0)) {
         struct.className = iprot.readString();
         struct.setClassNameIsSet(true);
@@ -552,9 +522,9 @@
       if (incoming.get(1)) {
         {
           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);
-          String _key161;
-          String _val162;
+          struct.options = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map160.size);
+          java.lang.String _key161;
+          java.lang.String _val162;
           for (int _i163 = 0; _i163 < _map160.size; ++_i163)
           {
             _key161 = iprot.readString();
@@ -567,5 +537,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 d561796..da93702 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum CompactionType implements org.apache.thrift.TEnum {
+public enum CompactionType implements org.apache.thrift.TEnum {
   MINOR(0),
   MERGE(1),
   MAJOR(2),
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 d946a87..ac4aef4 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/Condition.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/Condition.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -59,16 +32,13 @@
   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)3);
   private static final org.apache.thrift.protocol.TField ITERATORS_FIELD_DESC = new org.apache.thrift.protocol.TField("iterators", org.apache.thrift.protocol.TType.LIST, (short)4);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new ConditionStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new ConditionTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ConditionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ConditionTupleSchemeFactory();
 
   public Column column; // required
   public long timestamp; // optional
-  public ByteBuffer value; // optional
-  public List<IteratorSetting> iterators; // optional
+  public java.nio.ByteBuffer value; // optional
+  public java.util.List<IteratorSetting> iterators; // optional
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
   public enum _Fields implements org.apache.thrift.TFieldIdEnum {
@@ -77,10 +47,10 @@
     VALUE((short)3, "value"),
     ITERATORS((short)4, "iterators");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -109,21 +79,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -132,7 +102,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -141,9 +111,9 @@
   private static final int __TIMESTAMP_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
   private static final _Fields optionals[] = {_Fields.TIMESTAMP,_Fields.VALUE,_Fields.ITERATORS};
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.COLUMN, new org.apache.thrift.meta_data.FieldMetaData("column", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Column.class)));
     tmpMap.put(_Fields.TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("timestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
@@ -153,7 +123,7 @@
     tmpMap.put(_Fields.ITERATORS, new org.apache.thrift.meta_data.FieldMetaData("iterators", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
             new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class))));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Condition.class, metaDataMap);
   }
 
@@ -180,7 +150,7 @@
       this.value = org.apache.thrift.TBaseHelper.copyBinary(other.value);
     }
     if (other.isSetIterators()) {
-      List<IteratorSetting> __this__iterators = new ArrayList<IteratorSetting>(other.iterators.size());
+      java.util.List<IteratorSetting> __this__iterators = new java.util.ArrayList<IteratorSetting>(other.iterators.size());
       for (IteratorSetting other_element : other.iterators) {
         __this__iterators.add(new IteratorSetting(other_element));
       }
@@ -236,16 +206,16 @@
   }
 
   public void unsetTimestamp() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
   }
 
   /** Returns true if field timestamp is set (has been assigned a value) and false otherwise */
   public boolean isSetTimestamp() {
-    return EncodingUtils.testBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
   }
 
   public void setTimestampIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value);
   }
 
   public byte[] getValue() {
@@ -253,16 +223,16 @@
     return value == null ? null : value.array();
   }
 
-  public ByteBuffer bufferForValue() {
+  public java.nio.ByteBuffer bufferForValue() {
     return org.apache.thrift.TBaseHelper.copyBinary(value);
   }
 
   public Condition setValue(byte[] value) {
-    this.value = value == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(value, value.length));
+    this.value = value == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(value.clone());
     return this;
   }
 
-  public Condition setValue(ByteBuffer value) {
+  public Condition setValue(java.nio.ByteBuffer value) {
     this.value = org.apache.thrift.TBaseHelper.copyBinary(value);
     return this;
   }
@@ -292,16 +262,16 @@
 
   public void addToIterators(IteratorSetting elem) {
     if (this.iterators == null) {
-      this.iterators = new ArrayList<IteratorSetting>();
+      this.iterators = new java.util.ArrayList<IteratorSetting>();
     }
     this.iterators.add(elem);
   }
 
-  public List<IteratorSetting> getIterators() {
+  public java.util.List<IteratorSetting> getIterators() {
     return this.iterators;
   }
 
-  public Condition setIterators(List<IteratorSetting> iterators) {
+  public Condition setIterators(java.util.List<IteratorSetting> iterators) {
     this.iterators = iterators;
     return this;
   }
@@ -321,7 +291,7 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case COLUMN:
       if (value == null) {
@@ -335,7 +305,7 @@
       if (value == null) {
         unsetTimestamp();
       } else {
-        setTimestamp((Long)value);
+        setTimestamp((java.lang.Long)value);
       }
       break;
 
@@ -343,7 +313,11 @@
       if (value == null) {
         unsetValue();
       } else {
-        setValue((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setValue((byte[])value);
+        } else {
+          setValue((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -351,14 +325,14 @@
       if (value == null) {
         unsetIterators();
       } else {
-        setIterators((List<IteratorSetting>)value);
+        setIterators((java.util.List<IteratorSetting>)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case COLUMN:
       return getColumn();
@@ -373,13 +347,13 @@
       return getIterators();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -392,11 +366,11 @@
     case ITERATORS:
       return isSetIterators();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof Condition)
@@ -407,6 +381,8 @@
   public boolean equals(Condition that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_column = true && this.isSetColumn();
     boolean that_present_column = true && that.isSetColumn();
@@ -449,29 +425,25 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_column = true && (isSetColumn());
-    list.add(present_column);
-    if (present_column)
-      list.add(column);
+    hashCode = hashCode * 8191 + ((isSetColumn()) ? 131071 : 524287);
+    if (isSetColumn())
+      hashCode = hashCode * 8191 + column.hashCode();
 
-    boolean present_timestamp = true && (isSetTimestamp());
-    list.add(present_timestamp);
-    if (present_timestamp)
-      list.add(timestamp);
+    hashCode = hashCode * 8191 + ((isSetTimestamp()) ? 131071 : 524287);
+    if (isSetTimestamp())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(timestamp);
 
-    boolean present_value = true && (isSetValue());
-    list.add(present_value);
-    if (present_value)
-      list.add(value);
+    hashCode = hashCode * 8191 + ((isSetValue()) ? 131071 : 524287);
+    if (isSetValue())
+      hashCode = hashCode * 8191 + value.hashCode();
 
-    boolean present_iterators = true && (isSetIterators());
-    list.add(present_iterators);
-    if (present_iterators)
-      list.add(iterators);
+    hashCode = hashCode * 8191 + ((isSetIterators()) ? 131071 : 524287);
+    if (isSetIterators())
+      hashCode = hashCode * 8191 + iterators.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -482,7 +454,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetColumn()).compareTo(other.isSetColumn());
+    lastComparison = java.lang.Boolean.valueOf(isSetColumn()).compareTo(other.isSetColumn());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -492,7 +464,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetTimestamp()).compareTo(other.isSetTimestamp());
+    lastComparison = java.lang.Boolean.valueOf(isSetTimestamp()).compareTo(other.isSetTimestamp());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -502,7 +474,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
+    lastComparison = java.lang.Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -512,7 +484,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
+    lastComparison = java.lang.Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -530,16 +502,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("Condition(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("Condition(");
     boolean first = true;
 
     sb.append("column:");
@@ -595,7 +567,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -605,13 +577,13 @@
     }
   }
 
-  private static class ConditionStandardSchemeFactory implements SchemeFactory {
+  private static class ConditionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ConditionStandardScheme getScheme() {
       return new ConditionStandardScheme();
     }
   }
 
-  private static class ConditionStandardScheme extends StandardScheme<Condition> {
+  private static class ConditionStandardScheme extends org.apache.thrift.scheme.StandardScheme<Condition> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, Condition struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -652,7 +624,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list82 = iprot.readListBegin();
-                struct.iterators = new ArrayList<IteratorSetting>(_list82.size);
+                struct.iterators = new java.util.ArrayList<IteratorSetting>(_list82.size);
                 IteratorSetting _elem83;
                 for (int _i84 = 0; _i84 < _list82.size; ++_i84)
                 {
@@ -719,18 +691,18 @@
 
   }
 
-  private static class ConditionTupleSchemeFactory implements SchemeFactory {
+  private static class ConditionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ConditionTupleScheme getScheme() {
       return new ConditionTupleScheme();
     }
   }
 
-  private static class ConditionTupleScheme extends TupleScheme<Condition> {
+  private static class ConditionTupleScheme extends org.apache.thrift.scheme.TupleScheme<Condition> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, Condition struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetColumn()) {
         optionals.set(0);
       }
@@ -766,8 +738,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, Condition struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(4);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(4);
       if (incoming.get(0)) {
         struct.column = new Column();
         struct.column.read(iprot);
@@ -784,7 +756,7 @@
       if (incoming.get(3)) {
         {
           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);
+          struct.iterators = new java.util.ArrayList<IteratorSetting>(_list87.size);
           IteratorSetting _elem88;
           for (int _i89 = 0; _i89 < _list87.size; ++_i89)
           {
@@ -798,5 +770,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 c8626a5..6e5c1c3 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum ConditionalStatus implements org.apache.thrift.TEnum {
+public enum ConditionalStatus implements org.apache.thrift.TEnum {
   ACCEPTED(0),
   REJECTED(1),
   VIOLATED(2),
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 07f1338..a573685 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalUpdates.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalUpdates.java
@@ -15,66 +15,36 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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);
   private static final org.apache.thrift.protocol.TField UPDATES_FIELD_DESC = new org.apache.thrift.protocol.TField("updates", org.apache.thrift.protocol.TType.LIST, (short)3);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new ConditionalUpdatesStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new ConditionalUpdatesTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ConditionalUpdatesStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ConditionalUpdatesTupleSchemeFactory();
 
-  public List<Condition> conditions; // required
-  public List<ColumnUpdate> updates; // required
+  public java.util.List<Condition> conditions; // required
+  public java.util.List<ColumnUpdate> updates; // 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 {
     CONDITIONS((short)2, "conditions"),
     UPDATES((short)3, "updates");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -99,21 +69,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -122,22 +92,22 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.CONDITIONS, new org.apache.thrift.meta_data.FieldMetaData("conditions", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
             new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Condition.class))));
     tmpMap.put(_Fields.UPDATES, new org.apache.thrift.meta_data.FieldMetaData("updates", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
             new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnUpdate.class))));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ConditionalUpdates.class, metaDataMap);
   }
 
@@ -145,8 +115,8 @@
   }
 
   public ConditionalUpdates(
-    List<Condition> conditions,
-    List<ColumnUpdate> updates)
+    java.util.List<Condition> conditions,
+    java.util.List<ColumnUpdate> updates)
   {
     this();
     this.conditions = conditions;
@@ -158,14 +128,14 @@
    */
   public ConditionalUpdates(ConditionalUpdates other) {
     if (other.isSetConditions()) {
-      List<Condition> __this__conditions = new ArrayList<Condition>(other.conditions.size());
+      java.util.List<Condition> __this__conditions = new java.util.ArrayList<Condition>(other.conditions.size());
       for (Condition other_element : other.conditions) {
         __this__conditions.add(new Condition(other_element));
       }
       this.conditions = __this__conditions;
     }
     if (other.isSetUpdates()) {
-      List<ColumnUpdate> __this__updates = new ArrayList<ColumnUpdate>(other.updates.size());
+      java.util.List<ColumnUpdate> __this__updates = new java.util.ArrayList<ColumnUpdate>(other.updates.size());
       for (ColumnUpdate other_element : other.updates) {
         __this__updates.add(new ColumnUpdate(other_element));
       }
@@ -193,16 +163,16 @@
 
   public void addToConditions(Condition elem) {
     if (this.conditions == null) {
-      this.conditions = new ArrayList<Condition>();
+      this.conditions = new java.util.ArrayList<Condition>();
     }
     this.conditions.add(elem);
   }
 
-  public List<Condition> getConditions() {
+  public java.util.List<Condition> getConditions() {
     return this.conditions;
   }
 
-  public ConditionalUpdates setConditions(List<Condition> conditions) {
+  public ConditionalUpdates setConditions(java.util.List<Condition> conditions) {
     this.conditions = conditions;
     return this;
   }
@@ -232,16 +202,16 @@
 
   public void addToUpdates(ColumnUpdate elem) {
     if (this.updates == null) {
-      this.updates = new ArrayList<ColumnUpdate>();
+      this.updates = new java.util.ArrayList<ColumnUpdate>();
     }
     this.updates.add(elem);
   }
 
-  public List<ColumnUpdate> getUpdates() {
+  public java.util.List<ColumnUpdate> getUpdates() {
     return this.updates;
   }
 
-  public ConditionalUpdates setUpdates(List<ColumnUpdate> updates) {
+  public ConditionalUpdates setUpdates(java.util.List<ColumnUpdate> updates) {
     this.updates = updates;
     return this;
   }
@@ -261,13 +231,13 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case CONDITIONS:
       if (value == null) {
         unsetConditions();
       } else {
-        setConditions((List<Condition>)value);
+        setConditions((java.util.List<Condition>)value);
       }
       break;
 
@@ -275,14 +245,14 @@
       if (value == null) {
         unsetUpdates();
       } else {
-        setUpdates((List<ColumnUpdate>)value);
+        setUpdates((java.util.List<ColumnUpdate>)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case CONDITIONS:
       return getConditions();
@@ -291,13 +261,13 @@
       return getUpdates();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -306,11 +276,11 @@
     case UPDATES:
       return isSetUpdates();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof ConditionalUpdates)
@@ -321,6 +291,8 @@
   public boolean equals(ConditionalUpdates that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_conditions = true && this.isSetConditions();
     boolean that_present_conditions = true && that.isSetConditions();
@@ -345,19 +317,17 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_conditions = true && (isSetConditions());
-    list.add(present_conditions);
-    if (present_conditions)
-      list.add(conditions);
+    hashCode = hashCode * 8191 + ((isSetConditions()) ? 131071 : 524287);
+    if (isSetConditions())
+      hashCode = hashCode * 8191 + conditions.hashCode();
 
-    boolean present_updates = true && (isSetUpdates());
-    list.add(present_updates);
-    if (present_updates)
-      list.add(updates);
+    hashCode = hashCode * 8191 + ((isSetUpdates()) ? 131071 : 524287);
+    if (isSetUpdates())
+      hashCode = hashCode * 8191 + updates.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -368,7 +338,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetConditions()).compareTo(other.isSetConditions());
+    lastComparison = java.lang.Boolean.valueOf(isSetConditions()).compareTo(other.isSetConditions());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -378,7 +348,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetUpdates()).compareTo(other.isSetUpdates());
+    lastComparison = java.lang.Boolean.valueOf(isSetUpdates()).compareTo(other.isSetUpdates());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -396,16 +366,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("ConditionalUpdates(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("ConditionalUpdates(");
     boolean first = true;
 
     sb.append("conditions:");
@@ -440,7 +410,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -448,13 +418,13 @@
     }
   }
 
-  private static class ConditionalUpdatesStandardSchemeFactory implements SchemeFactory {
+  private static class ConditionalUpdatesStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ConditionalUpdatesStandardScheme getScheme() {
       return new ConditionalUpdatesStandardScheme();
     }
   }
 
-  private static class ConditionalUpdatesStandardScheme extends StandardScheme<ConditionalUpdates> {
+  private static class ConditionalUpdatesStandardScheme extends org.apache.thrift.scheme.StandardScheme<ConditionalUpdates> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, ConditionalUpdates struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -470,7 +440,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list90 = iprot.readListBegin();
-                struct.conditions = new ArrayList<Condition>(_list90.size);
+                struct.conditions = new java.util.ArrayList<Condition>(_list90.size);
                 Condition _elem91;
                 for (int _i92 = 0; _i92 < _list90.size; ++_i92)
                 {
@@ -489,7 +459,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list93 = iprot.readListBegin();
-                struct.updates = new ArrayList<ColumnUpdate>(_list93.size);
+                struct.updates = new java.util.ArrayList<ColumnUpdate>(_list93.size);
                 ColumnUpdate _elem94;
                 for (int _i95 = 0; _i95 < _list93.size; ++_i95)
                 {
@@ -549,18 +519,18 @@
 
   }
 
-  private static class ConditionalUpdatesTupleSchemeFactory implements SchemeFactory {
+  private static class ConditionalUpdatesTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ConditionalUpdatesTupleScheme getScheme() {
       return new ConditionalUpdatesTupleScheme();
     }
   }
 
-  private static class ConditionalUpdatesTupleScheme extends TupleScheme<ConditionalUpdates> {
+  private static class ConditionalUpdatesTupleScheme extends org.apache.thrift.scheme.TupleScheme<ConditionalUpdates> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, ConditionalUpdates struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetConditions()) {
         optionals.set(0);
       }
@@ -590,12 +560,12 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, ConditionalUpdates struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(2);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(2);
       if (incoming.get(0)) {
         {
           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);
+          struct.conditions = new java.util.ArrayList<Condition>(_list100.size);
           Condition _elem101;
           for (int _i102 = 0; _i102 < _list100.size; ++_i102)
           {
@@ -609,7 +579,7 @@
       if (incoming.get(1)) {
         {
           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);
+          struct.updates = new java.util.ArrayList<ColumnUpdate>(_list103.size);
           ColumnUpdate _elem104;
           for (int _i105 = 0; _i105 < _list103.size; ++_i105)
           {
@@ -623,5 +593,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 16c78a3..cd3ce5d 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalWriterOptions.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ConditionalWriterOptions.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -60,16 +33,13 @@
   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)4);
   private static final org.apache.thrift.protocol.TField DURABILITY_FIELD_DESC = new org.apache.thrift.protocol.TField("durability", org.apache.thrift.protocol.TType.I32, (short)5);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new ConditionalWriterOptionsStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new ConditionalWriterOptionsTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ConditionalWriterOptionsStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ConditionalWriterOptionsTupleSchemeFactory();
 
   public long maxMemory; // optional
   public long timeoutMs; // optional
   public int threads; // optional
-  public Set<ByteBuffer> authorizations; // optional
+  public java.util.Set<java.nio.ByteBuffer> authorizations; // optional
   /**
    * 
    * @see Durability
@@ -88,10 +58,10 @@
      */
     DURABILITY((short)5, "durability");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -122,21 +92,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -145,7 +115,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -156,9 +126,9 @@
   private static final int __THREADS_ISSET_ID = 2;
   private byte __isset_bitfield = 0;
   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;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.MAX_MEMORY, new org.apache.thrift.meta_data.FieldMetaData("maxMemory", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
     tmpMap.put(_Fields.TIMEOUT_MS, new org.apache.thrift.meta_data.FieldMetaData("timeoutMs", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
@@ -170,7 +140,7 @@
             new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING            , true))));
     tmpMap.put(_Fields.DURABILITY, new org.apache.thrift.meta_data.FieldMetaData("durability", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, Durability.class)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ConditionalWriterOptions.class, metaDataMap);
   }
 
@@ -186,7 +156,7 @@
     this.timeoutMs = other.timeoutMs;
     this.threads = other.threads;
     if (other.isSetAuthorizations()) {
-      Set<ByteBuffer> __this__authorizations = new HashSet<ByteBuffer>(other.authorizations);
+      java.util.Set<java.nio.ByteBuffer> __this__authorizations = new java.util.HashSet<java.nio.ByteBuffer>(other.authorizations);
       this.authorizations = __this__authorizations;
     }
     if (other.isSetDurability()) {
@@ -221,16 +191,16 @@
   }
 
   public void unsetMaxMemory() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __MAXMEMORY_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __MAXMEMORY_ISSET_ID);
   }
 
   /** Returns true if field maxMemory is set (has been assigned a value) and false otherwise */
   public boolean isSetMaxMemory() {
-    return EncodingUtils.testBit(__isset_bitfield, __MAXMEMORY_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __MAXMEMORY_ISSET_ID);
   }
 
   public void setMaxMemoryIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __MAXMEMORY_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __MAXMEMORY_ISSET_ID, value);
   }
 
   public long getTimeoutMs() {
@@ -244,16 +214,16 @@
   }
 
   public void unsetTimeoutMs() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID);
   }
 
   /** Returns true if field timeoutMs is set (has been assigned a value) and false otherwise */
   public boolean isSetTimeoutMs() {
-    return EncodingUtils.testBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID);
   }
 
   public void setTimeoutMsIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID, value);
   }
 
   public int getThreads() {
@@ -267,38 +237,38 @@
   }
 
   public void unsetThreads() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __THREADS_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __THREADS_ISSET_ID);
   }
 
   /** Returns true if field threads is set (has been assigned a value) and false otherwise */
   public boolean isSetThreads() {
-    return EncodingUtils.testBit(__isset_bitfield, __THREADS_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __THREADS_ISSET_ID);
   }
 
   public void setThreadsIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __THREADS_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __THREADS_ISSET_ID, value);
   }
 
   public int getAuthorizationsSize() {
     return (this.authorizations == null) ? 0 : this.authorizations.size();
   }
 
-  public java.util.Iterator<ByteBuffer> getAuthorizationsIterator() {
+  public java.util.Iterator<java.nio.ByteBuffer> getAuthorizationsIterator() {
     return (this.authorizations == null) ? null : this.authorizations.iterator();
   }
 
-  public void addToAuthorizations(ByteBuffer elem) {
+  public void addToAuthorizations(java.nio.ByteBuffer elem) {
     if (this.authorizations == null) {
-      this.authorizations = new HashSet<ByteBuffer>();
+      this.authorizations = new java.util.HashSet<java.nio.ByteBuffer>();
     }
     this.authorizations.add(elem);
   }
 
-  public Set<ByteBuffer> getAuthorizations() {
+  public java.util.Set<java.nio.ByteBuffer> getAuthorizations() {
     return this.authorizations;
   }
 
-  public ConditionalWriterOptions setAuthorizations(Set<ByteBuffer> authorizations) {
+  public ConditionalWriterOptions setAuthorizations(java.util.Set<java.nio.ByteBuffer> authorizations) {
     this.authorizations = authorizations;
     return this;
   }
@@ -350,13 +320,13 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MAX_MEMORY:
       if (value == null) {
         unsetMaxMemory();
       } else {
-        setMaxMemory((Long)value);
+        setMaxMemory((java.lang.Long)value);
       }
       break;
 
@@ -364,7 +334,7 @@
       if (value == null) {
         unsetTimeoutMs();
       } else {
-        setTimeoutMs((Long)value);
+        setTimeoutMs((java.lang.Long)value);
       }
       break;
 
@@ -372,7 +342,7 @@
       if (value == null) {
         unsetThreads();
       } else {
-        setThreads((Integer)value);
+        setThreads((java.lang.Integer)value);
       }
       break;
 
@@ -380,7 +350,7 @@
       if (value == null) {
         unsetAuthorizations();
       } else {
-        setAuthorizations((Set<ByteBuffer>)value);
+        setAuthorizations((java.util.Set<java.nio.ByteBuffer>)value);
       }
       break;
 
@@ -395,7 +365,7 @@
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MAX_MEMORY:
       return getMaxMemory();
@@ -413,13 +383,13 @@
       return getDurability();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -434,11 +404,11 @@
     case DURABILITY:
       return isSetDurability();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof ConditionalWriterOptions)
@@ -449,6 +419,8 @@
   public boolean equals(ConditionalWriterOptions that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_maxMemory = true && this.isSetMaxMemory();
     boolean that_present_maxMemory = true && that.isSetMaxMemory();
@@ -500,34 +472,29 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_maxMemory = true && (isSetMaxMemory());
-    list.add(present_maxMemory);
-    if (present_maxMemory)
-      list.add(maxMemory);
+    hashCode = hashCode * 8191 + ((isSetMaxMemory()) ? 131071 : 524287);
+    if (isSetMaxMemory())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(maxMemory);
 
-    boolean present_timeoutMs = true && (isSetTimeoutMs());
-    list.add(present_timeoutMs);
-    if (present_timeoutMs)
-      list.add(timeoutMs);
+    hashCode = hashCode * 8191 + ((isSetTimeoutMs()) ? 131071 : 524287);
+    if (isSetTimeoutMs())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(timeoutMs);
 
-    boolean present_threads = true && (isSetThreads());
-    list.add(present_threads);
-    if (present_threads)
-      list.add(threads);
+    hashCode = hashCode * 8191 + ((isSetThreads()) ? 131071 : 524287);
+    if (isSetThreads())
+      hashCode = hashCode * 8191 + threads;
 
-    boolean present_authorizations = true && (isSetAuthorizations());
-    list.add(present_authorizations);
-    if (present_authorizations)
-      list.add(authorizations);
+    hashCode = hashCode * 8191 + ((isSetAuthorizations()) ? 131071 : 524287);
+    if (isSetAuthorizations())
+      hashCode = hashCode * 8191 + authorizations.hashCode();
 
-    boolean present_durability = true && (isSetDurability());
-    list.add(present_durability);
-    if (present_durability)
-      list.add(durability.getValue());
+    hashCode = hashCode * 8191 + ((isSetDurability()) ? 131071 : 524287);
+    if (isSetDurability())
+      hashCode = hashCode * 8191 + durability.getValue();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -538,7 +505,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMaxMemory()).compareTo(other.isSetMaxMemory());
+    lastComparison = java.lang.Boolean.valueOf(isSetMaxMemory()).compareTo(other.isSetMaxMemory());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -548,7 +515,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetTimeoutMs()).compareTo(other.isSetTimeoutMs());
+    lastComparison = java.lang.Boolean.valueOf(isSetTimeoutMs()).compareTo(other.isSetTimeoutMs());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -558,7 +525,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetThreads()).compareTo(other.isSetThreads());
+    lastComparison = java.lang.Boolean.valueOf(isSetThreads()).compareTo(other.isSetThreads());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -568,7 +535,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
+    lastComparison = java.lang.Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -578,7 +545,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetDurability()).compareTo(other.isSetDurability());
+    lastComparison = java.lang.Boolean.valueOf(isSetDurability()).compareTo(other.isSetDurability());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -596,16 +563,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("ConditionalWriterOptions(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("ConditionalWriterOptions(");
     boolean first = true;
 
     if (isSetMaxMemory()) {
@@ -662,7 +629,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -672,13 +639,13 @@
     }
   }
 
-  private static class ConditionalWriterOptionsStandardSchemeFactory implements SchemeFactory {
+  private static class ConditionalWriterOptionsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ConditionalWriterOptionsStandardScheme getScheme() {
       return new ConditionalWriterOptionsStandardScheme();
     }
   }
 
-  private static class ConditionalWriterOptionsStandardScheme extends StandardScheme<ConditionalWriterOptions> {
+  private static class ConditionalWriterOptionsStandardScheme extends org.apache.thrift.scheme.StandardScheme<ConditionalWriterOptions> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, ConditionalWriterOptions struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -718,8 +685,8 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
               {
                 org.apache.thrift.protocol.TSet _set106 = iprot.readSetBegin();
-                struct.authorizations = new HashSet<ByteBuffer>(2*_set106.size);
-                ByteBuffer _elem107;
+                struct.authorizations = new java.util.HashSet<java.nio.ByteBuffer>(2*_set106.size);
+                java.nio.ByteBuffer _elem107;
                 for (int _i108 = 0; _i108 < _set106.size; ++_i108)
                 {
                   _elem107 = iprot.readBinary();
@@ -775,7 +742,7 @@
           oprot.writeFieldBegin(AUTHORIZATIONS_FIELD_DESC);
           {
             oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.authorizations.size()));
-            for (ByteBuffer _iter109 : struct.authorizations)
+            for (java.nio.ByteBuffer _iter109 : struct.authorizations)
             {
               oprot.writeBinary(_iter109);
             }
@@ -797,18 +764,18 @@
 
   }
 
-  private static class ConditionalWriterOptionsTupleSchemeFactory implements SchemeFactory {
+  private static class ConditionalWriterOptionsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ConditionalWriterOptionsTupleScheme getScheme() {
       return new ConditionalWriterOptionsTupleScheme();
     }
   }
 
-  private static class ConditionalWriterOptionsTupleScheme extends TupleScheme<ConditionalWriterOptions> {
+  private static class ConditionalWriterOptionsTupleScheme extends org.apache.thrift.scheme.TupleScheme<ConditionalWriterOptions> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, ConditionalWriterOptions struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMaxMemory()) {
         optionals.set(0);
       }
@@ -837,7 +804,7 @@
       if (struct.isSetAuthorizations()) {
         {
           oprot.writeI32(struct.authorizations.size());
-          for (ByteBuffer _iter110 : struct.authorizations)
+          for (java.nio.ByteBuffer _iter110 : struct.authorizations)
           {
             oprot.writeBinary(_iter110);
           }
@@ -850,8 +817,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, ConditionalWriterOptions struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(5);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(5);
       if (incoming.get(0)) {
         struct.maxMemory = iprot.readI64();
         struct.setMaxMemoryIsSet(true);
@@ -867,8 +834,8 @@
       if (incoming.get(3)) {
         {
           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);
-          ByteBuffer _elem112;
+          struct.authorizations = new java.util.HashSet<java.nio.ByteBuffer>(2*_set111.size);
+          java.nio.ByteBuffer _elem112;
           for (int _i113 = 0; _i113 < _set111.size; ++_i113)
           {
             _elem112 = iprot.readBinary();
@@ -884,5 +851,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 c49910f..f66a93c 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/DiskUsage.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/DiskUsage.java
@@ -15,55 +15,25 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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);
   private static final org.apache.thrift.protocol.TField USAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("usage", org.apache.thrift.protocol.TType.I64, (short)2);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new DiskUsageStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new DiskUsageTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new DiskUsageStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new DiskUsageTupleSchemeFactory();
 
-  public List<String> tables; // required
+  public java.util.List<java.lang.String> tables; // required
   public long usage; // required
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -71,10 +41,10 @@
     TABLES((short)1, "tables"),
     USAGE((short)2, "usage");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -99,21 +69,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -122,7 +92,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -130,15 +100,15 @@
   // isset id assignments
   private static final int __USAGE_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.TABLES, new org.apache.thrift.meta_data.FieldMetaData("tables", 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.USAGE, new org.apache.thrift.meta_data.FieldMetaData("usage", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(DiskUsage.class, metaDataMap);
   }
 
@@ -146,7 +116,7 @@
   }
 
   public DiskUsage(
-    List<String> tables,
+    java.util.List<java.lang.String> tables,
     long usage)
   {
     this();
@@ -161,7 +131,7 @@
   public DiskUsage(DiskUsage other) {
     __isset_bitfield = other.__isset_bitfield;
     if (other.isSetTables()) {
-      List<String> __this__tables = new ArrayList<String>(other.tables);
+      java.util.List<java.lang.String> __this__tables = new java.util.ArrayList<java.lang.String>(other.tables);
       this.tables = __this__tables;
     }
     this.usage = other.usage;
@@ -182,22 +152,22 @@
     return (this.tables == null) ? 0 : this.tables.size();
   }
 
-  public java.util.Iterator<String> getTablesIterator() {
+  public java.util.Iterator<java.lang.String> getTablesIterator() {
     return (this.tables == null) ? null : this.tables.iterator();
   }
 
-  public void addToTables(String elem) {
+  public void addToTables(java.lang.String elem) {
     if (this.tables == null) {
-      this.tables = new ArrayList<String>();
+      this.tables = new java.util.ArrayList<java.lang.String>();
     }
     this.tables.add(elem);
   }
 
-  public List<String> getTables() {
+  public java.util.List<java.lang.String> getTables() {
     return this.tables;
   }
 
-  public DiskUsage setTables(List<String> tables) {
+  public DiskUsage setTables(java.util.List<java.lang.String> tables) {
     this.tables = tables;
     return this;
   }
@@ -228,25 +198,25 @@
   }
 
   public void unsetUsage() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __USAGE_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __USAGE_ISSET_ID);
   }
 
   /** Returns true if field usage is set (has been assigned a value) and false otherwise */
   public boolean isSetUsage() {
-    return EncodingUtils.testBit(__isset_bitfield, __USAGE_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __USAGE_ISSET_ID);
   }
 
   public void setUsageIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __USAGE_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __USAGE_ISSET_ID, value);
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case TABLES:
       if (value == null) {
         unsetTables();
       } else {
-        setTables((List<String>)value);
+        setTables((java.util.List<java.lang.String>)value);
       }
       break;
 
@@ -254,14 +224,14 @@
       if (value == null) {
         unsetUsage();
       } else {
-        setUsage((Long)value);
+        setUsage((java.lang.Long)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case TABLES:
       return getTables();
@@ -270,13 +240,13 @@
       return getUsage();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -285,11 +255,11 @@
     case USAGE:
       return isSetUsage();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof DiskUsage)
@@ -300,6 +270,8 @@
   public boolean equals(DiskUsage that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_tables = true && this.isSetTables();
     boolean that_present_tables = true && that.isSetTables();
@@ -324,19 +296,15 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_tables = true && (isSetTables());
-    list.add(present_tables);
-    if (present_tables)
-      list.add(tables);
+    hashCode = hashCode * 8191 + ((isSetTables()) ? 131071 : 524287);
+    if (isSetTables())
+      hashCode = hashCode * 8191 + tables.hashCode();
 
-    boolean present_usage = true;
-    list.add(present_usage);
-    if (present_usage)
-      list.add(usage);
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(usage);
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -347,7 +315,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetTables()).compareTo(other.isSetTables());
+    lastComparison = java.lang.Boolean.valueOf(isSetTables()).compareTo(other.isSetTables());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -357,7 +325,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetUsage()).compareTo(other.isSetUsage());
+    lastComparison = java.lang.Boolean.valueOf(isSetUsage()).compareTo(other.isSetUsage());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -375,16 +343,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("DiskUsage(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("DiskUsage(");
     boolean first = true;
 
     sb.append("tables:");
@@ -415,7 +383,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -425,13 +393,13 @@
     }
   }
 
-  private static class DiskUsageStandardSchemeFactory implements SchemeFactory {
+  private static class DiskUsageStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public DiskUsageStandardScheme getScheme() {
       return new DiskUsageStandardScheme();
     }
   }
 
-  private static class DiskUsageStandardScheme extends StandardScheme<DiskUsage> {
+  private static class DiskUsageStandardScheme extends org.apache.thrift.scheme.StandardScheme<DiskUsage> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, DiskUsage struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -447,8 +415,8 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
-                struct.tables = new ArrayList<String>(_list0.size);
-                String _elem1;
+                struct.tables = new java.util.ArrayList<java.lang.String>(_list0.size);
+                java.lang.String _elem1;
                 for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                 {
                   _elem1 = iprot.readString();
@@ -488,7 +456,7 @@
         oprot.writeFieldBegin(TABLES_FIELD_DESC);
         {
           oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.tables.size()));
-          for (String _iter3 : struct.tables)
+          for (java.lang.String _iter3 : struct.tables)
           {
             oprot.writeString(_iter3);
           }
@@ -505,18 +473,18 @@
 
   }
 
-  private static class DiskUsageTupleSchemeFactory implements SchemeFactory {
+  private static class DiskUsageTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public DiskUsageTupleScheme getScheme() {
       return new DiskUsageTupleScheme();
     }
   }
 
-  private static class DiskUsageTupleScheme extends TupleScheme<DiskUsage> {
+  private static class DiskUsageTupleScheme extends org.apache.thrift.scheme.TupleScheme<DiskUsage> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, DiskUsage struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetTables()) {
         optionals.set(0);
       }
@@ -527,7 +495,7 @@
       if (struct.isSetTables()) {
         {
           oprot.writeI32(struct.tables.size());
-          for (String _iter4 : struct.tables)
+          for (java.lang.String _iter4 : struct.tables)
           {
             oprot.writeString(_iter4);
           }
@@ -540,13 +508,13 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, DiskUsage struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(2);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(2);
       if (incoming.get(0)) {
         {
           org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
-          struct.tables = new ArrayList<String>(_list5.size);
-          String _elem6;
+          struct.tables = new java.util.ArrayList<java.lang.String>(_list5.size);
+          java.lang.String _elem6;
           for (int _i7 = 0; _i7 < _list5.size; ++_i7)
           {
             _elem6 = iprot.readString();
@@ -562,5 +530,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 daa16c8..8f685df 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum Durability implements org.apache.thrift.TEnum {
+public enum Durability implements org.apache.thrift.TEnum {
   DEFAULT(0),
   NONE(1),
   LOG(2),
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 65408bd..8ab316f 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum IteratorScope implements org.apache.thrift.TEnum {
+public enum IteratorScope implements org.apache.thrift.TEnum {
   MINC(0),
   MAJC(1),
   SCAN(2);
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 826c46f..dec8c0a 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/IteratorSetting.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/IteratorSetting.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -59,16 +32,13 @@
   private static final org.apache.thrift.protocol.TField ITERATOR_CLASS_FIELD_DESC = new org.apache.thrift.protocol.TField("iteratorClass", org.apache.thrift.protocol.TType.STRING, (short)3);
   private static final org.apache.thrift.protocol.TField PROPERTIES_FIELD_DESC = new org.apache.thrift.protocol.TField("properties", org.apache.thrift.protocol.TType.MAP, (short)4);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new IteratorSettingStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new IteratorSettingTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new IteratorSettingStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new IteratorSettingTupleSchemeFactory();
 
   public int priority; // required
-  public String name; // required
-  public String iteratorClass; // required
-  public Map<String,String> properties; // required
+  public java.lang.String name; // required
+  public java.lang.String iteratorClass; // required
+  public java.util.Map<java.lang.String,java.lang.String> properties; // 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 {
@@ -77,10 +47,10 @@
     ITERATOR_CLASS((short)3, "iteratorClass"),
     PROPERTIES((short)4, "properties");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -109,21 +79,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -132,7 +102,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -140,9 +110,9 @@
   // isset id assignments
   private static final int __PRIORITY_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.PRIORITY, new org.apache.thrift.meta_data.FieldMetaData("priority", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
     tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -153,7 +123,7 @@
         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))));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(IteratorSetting.class, metaDataMap);
   }
 
@@ -162,9 +132,9 @@
 
   public IteratorSetting(
     int priority,
-    String name,
-    String iteratorClass,
-    Map<String,String> properties)
+    java.lang.String name,
+    java.lang.String iteratorClass,
+    java.util.Map<java.lang.String,java.lang.String> properties)
   {
     this();
     this.priority = priority;
@@ -187,7 +157,7 @@
       this.iteratorClass = other.iteratorClass;
     }
     if (other.isSetProperties()) {
-      Map<String,String> __this__properties = new HashMap<String,String>(other.properties);
+      java.util.Map<java.lang.String,java.lang.String> __this__properties = new java.util.HashMap<java.lang.String,java.lang.String>(other.properties);
       this.properties = __this__properties;
     }
   }
@@ -216,23 +186,23 @@
   }
 
   public void unsetPriority() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __PRIORITY_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __PRIORITY_ISSET_ID);
   }
 
   /** Returns true if field priority is set (has been assigned a value) and false otherwise */
   public boolean isSetPriority() {
-    return EncodingUtils.testBit(__isset_bitfield, __PRIORITY_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __PRIORITY_ISSET_ID);
   }
 
   public void setPriorityIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __PRIORITY_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __PRIORITY_ISSET_ID, value);
   }
 
-  public String getName() {
+  public java.lang.String getName() {
     return this.name;
   }
 
-  public IteratorSetting setName(String name) {
+  public IteratorSetting setName(java.lang.String name) {
     this.name = name;
     return this;
   }
@@ -252,11 +222,11 @@
     }
   }
 
-  public String getIteratorClass() {
+  public java.lang.String getIteratorClass() {
     return this.iteratorClass;
   }
 
-  public IteratorSetting setIteratorClass(String iteratorClass) {
+  public IteratorSetting setIteratorClass(java.lang.String iteratorClass) {
     this.iteratorClass = iteratorClass;
     return this;
   }
@@ -280,18 +250,18 @@
     return (this.properties == null) ? 0 : this.properties.size();
   }
 
-  public void putToProperties(String key, String val) {
+  public void putToProperties(java.lang.String key, java.lang.String val) {
     if (this.properties == null) {
-      this.properties = new HashMap<String,String>();
+      this.properties = new java.util.HashMap<java.lang.String,java.lang.String>();
     }
     this.properties.put(key, val);
   }
 
-  public Map<String,String> getProperties() {
+  public java.util.Map<java.lang.String,java.lang.String> getProperties() {
     return this.properties;
   }
 
-  public IteratorSetting setProperties(Map<String,String> properties) {
+  public IteratorSetting setProperties(java.util.Map<java.lang.String,java.lang.String> properties) {
     this.properties = properties;
     return this;
   }
@@ -311,13 +281,13 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case PRIORITY:
       if (value == null) {
         unsetPriority();
       } else {
-        setPriority((Integer)value);
+        setPriority((java.lang.Integer)value);
       }
       break;
 
@@ -325,7 +295,7 @@
       if (value == null) {
         unsetName();
       } else {
-        setName((String)value);
+        setName((java.lang.String)value);
       }
       break;
 
@@ -333,7 +303,7 @@
       if (value == null) {
         unsetIteratorClass();
       } else {
-        setIteratorClass((String)value);
+        setIteratorClass((java.lang.String)value);
       }
       break;
 
@@ -341,14 +311,14 @@
       if (value == null) {
         unsetProperties();
       } else {
-        setProperties((Map<String,String>)value);
+        setProperties((java.util.Map<java.lang.String,java.lang.String>)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case PRIORITY:
       return getPriority();
@@ -363,13 +333,13 @@
       return getProperties();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -382,11 +352,11 @@
     case PROPERTIES:
       return isSetProperties();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof IteratorSetting)
@@ -397,6 +367,8 @@
   public boolean equals(IteratorSetting that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_priority = true;
     boolean that_present_priority = true;
@@ -439,29 +411,23 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_priority = true;
-    list.add(present_priority);
-    if (present_priority)
-      list.add(priority);
+    hashCode = hashCode * 8191 + priority;
 
-    boolean present_name = true && (isSetName());
-    list.add(present_name);
-    if (present_name)
-      list.add(name);
+    hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287);
+    if (isSetName())
+      hashCode = hashCode * 8191 + name.hashCode();
 
-    boolean present_iteratorClass = true && (isSetIteratorClass());
-    list.add(present_iteratorClass);
-    if (present_iteratorClass)
-      list.add(iteratorClass);
+    hashCode = hashCode * 8191 + ((isSetIteratorClass()) ? 131071 : 524287);
+    if (isSetIteratorClass())
+      hashCode = hashCode * 8191 + iteratorClass.hashCode();
 
-    boolean present_properties = true && (isSetProperties());
-    list.add(present_properties);
-    if (present_properties)
-      list.add(properties);
+    hashCode = hashCode * 8191 + ((isSetProperties()) ? 131071 : 524287);
+    if (isSetProperties())
+      hashCode = hashCode * 8191 + properties.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -472,7 +438,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetPriority()).compareTo(other.isSetPriority());
+    lastComparison = java.lang.Boolean.valueOf(isSetPriority()).compareTo(other.isSetPriority());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -482,7 +448,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName());
+    lastComparison = java.lang.Boolean.valueOf(isSetName()).compareTo(other.isSetName());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -492,7 +458,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetIteratorClass()).compareTo(other.isSetIteratorClass());
+    lastComparison = java.lang.Boolean.valueOf(isSetIteratorClass()).compareTo(other.isSetIteratorClass());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -502,7 +468,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetProperties()).compareTo(other.isSetProperties());
+    lastComparison = java.lang.Boolean.valueOf(isSetProperties()).compareTo(other.isSetProperties());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -520,16 +486,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("IteratorSetting(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("IteratorSetting(");
     boolean first = true;
 
     sb.append("priority:");
@@ -576,7 +542,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -586,13 +552,13 @@
     }
   }
 
-  private static class IteratorSettingStandardSchemeFactory implements SchemeFactory {
+  private static class IteratorSettingStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public IteratorSettingStandardScheme getScheme() {
       return new IteratorSettingStandardScheme();
     }
   }
 
-  private static class IteratorSettingStandardScheme extends StandardScheme<IteratorSetting> {
+  private static class IteratorSettingStandardScheme extends org.apache.thrift.scheme.StandardScheme<IteratorSetting> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, IteratorSetting struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -632,9 +598,9 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
               {
                 org.apache.thrift.protocol.TMap _map16 = iprot.readMapBegin();
-                struct.properties = new HashMap<String,String>(2*_map16.size);
-                String _key17;
-                String _val18;
+                struct.properties = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map16.size);
+                java.lang.String _key17;
+                java.lang.String _val18;
                 for (int _i19 = 0; _i19 < _map16.size; ++_i19)
                 {
                   _key17 = iprot.readString();
@@ -680,7 +646,7 @@
         oprot.writeFieldBegin(PROPERTIES_FIELD_DESC);
         {
           oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.properties.size()));
-          for (Map.Entry<String, String> _iter20 : struct.properties.entrySet())
+          for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter20 : struct.properties.entrySet())
           {
             oprot.writeString(_iter20.getKey());
             oprot.writeString(_iter20.getValue());
@@ -695,18 +661,18 @@
 
   }
 
-  private static class IteratorSettingTupleSchemeFactory implements SchemeFactory {
+  private static class IteratorSettingTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public IteratorSettingTupleScheme getScheme() {
       return new IteratorSettingTupleScheme();
     }
   }
 
-  private static class IteratorSettingTupleScheme extends TupleScheme<IteratorSetting> {
+  private static class IteratorSettingTupleScheme extends org.apache.thrift.scheme.TupleScheme<IteratorSetting> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, IteratorSetting struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetPriority()) {
         optionals.set(0);
       }
@@ -732,7 +698,7 @@
       if (struct.isSetProperties()) {
         {
           oprot.writeI32(struct.properties.size());
-          for (Map.Entry<String, String> _iter21 : struct.properties.entrySet())
+          for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter21 : struct.properties.entrySet())
           {
             oprot.writeString(_iter21.getKey());
             oprot.writeString(_iter21.getValue());
@@ -743,8 +709,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, IteratorSetting struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(4);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(4);
       if (incoming.get(0)) {
         struct.priority = iprot.readI32();
         struct.setPriorityIsSet(true);
@@ -760,9 +726,9 @@
       if (incoming.get(3)) {
         {
           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);
-          String _key23;
-          String _val24;
+          struct.properties = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map22.size);
+          java.lang.String _key23;
+          java.lang.String _val24;
           for (int _i25 = 0; _i25 < _map22.size; ++_i25)
           {
             _key23 = iprot.readString();
@@ -775,5 +741,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 93237c5..d935c9a 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/Key.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/Key.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -60,16 +33,13 @@
   private static final org.apache.thrift.protocol.TField COL_VISIBILITY_FIELD_DESC = new org.apache.thrift.protocol.TField("colVisibility", org.apache.thrift.protocol.TType.STRING, (short)4);
   private static final org.apache.thrift.protocol.TField TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("timestamp", org.apache.thrift.protocol.TType.I64, (short)5);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new KeyStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new KeyTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new KeyStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new KeyTupleSchemeFactory();
 
-  public ByteBuffer row; // required
-  public ByteBuffer colFamily; // required
-  public ByteBuffer colQualifier; // required
-  public ByteBuffer colVisibility; // required
+  public java.nio.ByteBuffer row; // required
+  public java.nio.ByteBuffer colFamily; // required
+  public java.nio.ByteBuffer colQualifier; // required
+  public java.nio.ByteBuffer colVisibility; // required
   public long timestamp; // optional
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -80,10 +50,10 @@
     COL_VISIBILITY((short)4, "colVisibility"),
     TIMESTAMP((short)5, "timestamp");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -114,21 +84,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -137,7 +107,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -146,9 +116,9 @@
   private static final int __TIMESTAMP_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
   private static final _Fields optionals[] = {_Fields.TIMESTAMP};
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.ROW, new org.apache.thrift.meta_data.FieldMetaData("row", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
     tmpMap.put(_Fields.COL_FAMILY, new org.apache.thrift.meta_data.FieldMetaData("colFamily", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -159,7 +129,7 @@
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
     tmpMap.put(_Fields.TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("timestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Key.class, metaDataMap);
   }
 
@@ -169,10 +139,10 @@
   }
 
   public Key(
-    ByteBuffer row,
-    ByteBuffer colFamily,
-    ByteBuffer colQualifier,
-    ByteBuffer colVisibility)
+    java.nio.ByteBuffer row,
+    java.nio.ByteBuffer colFamily,
+    java.nio.ByteBuffer colQualifier,
+    java.nio.ByteBuffer colVisibility)
   {
     this();
     this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
@@ -220,16 +190,16 @@
     return row == null ? null : row.array();
   }
 
-  public ByteBuffer bufferForRow() {
+  public java.nio.ByteBuffer bufferForRow() {
     return org.apache.thrift.TBaseHelper.copyBinary(row);
   }
 
   public Key setRow(byte[] row) {
-    this.row = row == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(row, row.length));
+    this.row = row == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(row.clone());
     return this;
   }
 
-  public Key setRow(ByteBuffer row) {
+  public Key setRow(java.nio.ByteBuffer row) {
     this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
     return this;
   }
@@ -254,16 +224,16 @@
     return colFamily == null ? null : colFamily.array();
   }
 
-  public ByteBuffer bufferForColFamily() {
+  public java.nio.ByteBuffer bufferForColFamily() {
     return org.apache.thrift.TBaseHelper.copyBinary(colFamily);
   }
 
   public Key setColFamily(byte[] colFamily) {
-    this.colFamily = colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colFamily, colFamily.length));
+    this.colFamily = colFamily == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colFamily.clone());
     return this;
   }
 
-  public Key setColFamily(ByteBuffer colFamily) {
+  public Key setColFamily(java.nio.ByteBuffer colFamily) {
     this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
     return this;
   }
@@ -288,16 +258,16 @@
     return colQualifier == null ? null : colQualifier.array();
   }
 
-  public ByteBuffer bufferForColQualifier() {
+  public java.nio.ByteBuffer bufferForColQualifier() {
     return org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
   }
 
   public Key setColQualifier(byte[] colQualifier) {
-    this.colQualifier = colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colQualifier, colQualifier.length));
+    this.colQualifier = colQualifier == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colQualifier.clone());
     return this;
   }
 
-  public Key setColQualifier(ByteBuffer colQualifier) {
+  public Key setColQualifier(java.nio.ByteBuffer colQualifier) {
     this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
     return this;
   }
@@ -322,16 +292,16 @@
     return colVisibility == null ? null : colVisibility.array();
   }
 
-  public ByteBuffer bufferForColVisibility() {
+  public java.nio.ByteBuffer bufferForColVisibility() {
     return org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
   }
 
   public Key setColVisibility(byte[] colVisibility) {
-    this.colVisibility = colVisibility == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colVisibility, colVisibility.length));
+    this.colVisibility = colVisibility == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colVisibility.clone());
     return this;
   }
 
-  public Key setColVisibility(ByteBuffer colVisibility) {
+  public Key setColVisibility(java.nio.ByteBuffer colVisibility) {
     this.colVisibility = org.apache.thrift.TBaseHelper.copyBinary(colVisibility);
     return this;
   }
@@ -362,25 +332,29 @@
   }
 
   public void unsetTimestamp() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
   }
 
   /** Returns true if field timestamp is set (has been assigned a value) and false otherwise */
   public boolean isSetTimestamp() {
-    return EncodingUtils.testBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
   }
 
   public void setTimestampIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value);
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case ROW:
       if (value == null) {
         unsetRow();
       } else {
-        setRow((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setRow((byte[])value);
+        } else {
+          setRow((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -388,7 +362,11 @@
       if (value == null) {
         unsetColFamily();
       } else {
-        setColFamily((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColFamily((byte[])value);
+        } else {
+          setColFamily((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -396,7 +374,11 @@
       if (value == null) {
         unsetColQualifier();
       } else {
-        setColQualifier((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColQualifier((byte[])value);
+        } else {
+          setColQualifier((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -404,7 +386,11 @@
       if (value == null) {
         unsetColVisibility();
       } else {
-        setColVisibility((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColVisibility((byte[])value);
+        } else {
+          setColVisibility((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -412,14 +398,14 @@
       if (value == null) {
         unsetTimestamp();
       } else {
-        setTimestamp((Long)value);
+        setTimestamp((java.lang.Long)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case ROW:
       return getRow();
@@ -437,13 +423,13 @@
       return getTimestamp();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -458,11 +444,11 @@
     case TIMESTAMP:
       return isSetTimestamp();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof Key)
@@ -473,6 +459,8 @@
   public boolean equals(Key that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_row = true && this.isSetRow();
     boolean that_present_row = true && that.isSetRow();
@@ -524,34 +512,29 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_row = true && (isSetRow());
-    list.add(present_row);
-    if (present_row)
-      list.add(row);
+    hashCode = hashCode * 8191 + ((isSetRow()) ? 131071 : 524287);
+    if (isSetRow())
+      hashCode = hashCode * 8191 + row.hashCode();
 
-    boolean present_colFamily = true && (isSetColFamily());
-    list.add(present_colFamily);
-    if (present_colFamily)
-      list.add(colFamily);
+    hashCode = hashCode * 8191 + ((isSetColFamily()) ? 131071 : 524287);
+    if (isSetColFamily())
+      hashCode = hashCode * 8191 + colFamily.hashCode();
 
-    boolean present_colQualifier = true && (isSetColQualifier());
-    list.add(present_colQualifier);
-    if (present_colQualifier)
-      list.add(colQualifier);
+    hashCode = hashCode * 8191 + ((isSetColQualifier()) ? 131071 : 524287);
+    if (isSetColQualifier())
+      hashCode = hashCode * 8191 + colQualifier.hashCode();
 
-    boolean present_colVisibility = true && (isSetColVisibility());
-    list.add(present_colVisibility);
-    if (present_colVisibility)
-      list.add(colVisibility);
+    hashCode = hashCode * 8191 + ((isSetColVisibility()) ? 131071 : 524287);
+    if (isSetColVisibility())
+      hashCode = hashCode * 8191 + colVisibility.hashCode();
 
-    boolean present_timestamp = true && (isSetTimestamp());
-    list.add(present_timestamp);
-    if (present_timestamp)
-      list.add(timestamp);
+    hashCode = hashCode * 8191 + ((isSetTimestamp()) ? 131071 : 524287);
+    if (isSetTimestamp())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(timestamp);
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -562,7 +545,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetRow()).compareTo(other.isSetRow());
+    lastComparison = java.lang.Boolean.valueOf(isSetRow()).compareTo(other.isSetRow());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -572,7 +555,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColFamily()).compareTo(other.isSetColFamily());
+    lastComparison = java.lang.Boolean.valueOf(isSetColFamily()).compareTo(other.isSetColFamily());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -582,7 +565,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColQualifier()).compareTo(other.isSetColQualifier());
+    lastComparison = java.lang.Boolean.valueOf(isSetColQualifier()).compareTo(other.isSetColQualifier());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -592,7 +575,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColVisibility()).compareTo(other.isSetColVisibility());
+    lastComparison = java.lang.Boolean.valueOf(isSetColVisibility()).compareTo(other.isSetColVisibility());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -602,7 +585,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetTimestamp()).compareTo(other.isSetTimestamp());
+    lastComparison = java.lang.Boolean.valueOf(isSetTimestamp()).compareTo(other.isSetTimestamp());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -620,16 +603,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("Key(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("Key(");
     boolean first = true;
 
     sb.append("row:");
@@ -686,7 +669,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -696,13 +679,13 @@
     }
   }
 
-  private static class KeyStandardSchemeFactory implements SchemeFactory {
+  private static class KeyStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public KeyStandardScheme getScheme() {
       return new KeyStandardScheme();
     }
   }
 
-  private static class KeyStandardScheme extends StandardScheme<Key> {
+  private static class KeyStandardScheme extends org.apache.thrift.scheme.StandardScheme<Key> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, Key struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -800,18 +783,18 @@
 
   }
 
-  private static class KeyTupleSchemeFactory implements SchemeFactory {
+  private static class KeyTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public KeyTupleScheme getScheme() {
       return new KeyTupleScheme();
     }
   }
 
-  private static class KeyTupleScheme extends TupleScheme<Key> {
+  private static class KeyTupleScheme extends org.apache.thrift.scheme.TupleScheme<Key> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, Key struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetRow()) {
         optionals.set(0);
       }
@@ -847,8 +830,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, Key struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(5);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(5);
       if (incoming.get(0)) {
         struct.row = iprot.readBinary();
         struct.setRowIsSet(true);
@@ -872,5 +855,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 09001c6..8df1b9e 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/KeyExtent.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/KeyExtent.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -58,15 +31,12 @@
   private static final org.apache.thrift.protocol.TField END_ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("endRow", org.apache.thrift.protocol.TType.STRING, (short)2);
   private static final org.apache.thrift.protocol.TField PREV_END_ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("prevEndRow", 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 KeyExtentStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new KeyExtentTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new KeyExtentStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new KeyExtentTupleSchemeFactory();
 
-  public String tableId; // required
-  public ByteBuffer endRow; // required
-  public ByteBuffer prevEndRow; // required
+  public java.lang.String tableId; // required
+  public java.nio.ByteBuffer endRow; // required
+  public java.nio.ByteBuffer prevEndRow; // 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 {
@@ -74,10 +44,10 @@
     END_ROW((short)2, "endRow"),
     PREV_END_ROW((short)3, "prevEndRow");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -104,21 +74,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -127,22 +97,22 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.TABLE_ID, new org.apache.thrift.meta_data.FieldMetaData("tableId", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
     tmpMap.put(_Fields.END_ROW, new org.apache.thrift.meta_data.FieldMetaData("endRow", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
     tmpMap.put(_Fields.PREV_END_ROW, new org.apache.thrift.meta_data.FieldMetaData("prevEndRow", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(KeyExtent.class, metaDataMap);
   }
 
@@ -150,9 +120,9 @@
   }
 
   public KeyExtent(
-    String tableId,
-    ByteBuffer endRow,
-    ByteBuffer prevEndRow)
+    java.lang.String tableId,
+    java.nio.ByteBuffer endRow,
+    java.nio.ByteBuffer prevEndRow)
   {
     this();
     this.tableId = tableId;
@@ -186,11 +156,11 @@
     this.prevEndRow = null;
   }
 
-  public String getTableId() {
+  public java.lang.String getTableId() {
     return this.tableId;
   }
 
-  public KeyExtent setTableId(String tableId) {
+  public KeyExtent setTableId(java.lang.String tableId) {
     this.tableId = tableId;
     return this;
   }
@@ -215,16 +185,16 @@
     return endRow == null ? null : endRow.array();
   }
 
-  public ByteBuffer bufferForEndRow() {
+  public java.nio.ByteBuffer bufferForEndRow() {
     return org.apache.thrift.TBaseHelper.copyBinary(endRow);
   }
 
   public KeyExtent setEndRow(byte[] endRow) {
-    this.endRow = endRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(endRow, endRow.length));
+    this.endRow = endRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(endRow.clone());
     return this;
   }
 
-  public KeyExtent setEndRow(ByteBuffer endRow) {
+  public KeyExtent setEndRow(java.nio.ByteBuffer endRow) {
     this.endRow = org.apache.thrift.TBaseHelper.copyBinary(endRow);
     return this;
   }
@@ -249,16 +219,16 @@
     return prevEndRow == null ? null : prevEndRow.array();
   }
 
-  public ByteBuffer bufferForPrevEndRow() {
+  public java.nio.ByteBuffer bufferForPrevEndRow() {
     return org.apache.thrift.TBaseHelper.copyBinary(prevEndRow);
   }
 
   public KeyExtent setPrevEndRow(byte[] prevEndRow) {
-    this.prevEndRow = prevEndRow == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(prevEndRow, prevEndRow.length));
+    this.prevEndRow = prevEndRow == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(prevEndRow.clone());
     return this;
   }
 
-  public KeyExtent setPrevEndRow(ByteBuffer prevEndRow) {
+  public KeyExtent setPrevEndRow(java.nio.ByteBuffer prevEndRow) {
     this.prevEndRow = org.apache.thrift.TBaseHelper.copyBinary(prevEndRow);
     return this;
   }
@@ -278,13 +248,13 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case TABLE_ID:
       if (value == null) {
         unsetTableId();
       } else {
-        setTableId((String)value);
+        setTableId((java.lang.String)value);
       }
       break;
 
@@ -292,7 +262,11 @@
       if (value == null) {
         unsetEndRow();
       } else {
-        setEndRow((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setEndRow((byte[])value);
+        } else {
+          setEndRow((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -300,14 +274,18 @@
       if (value == null) {
         unsetPrevEndRow();
       } else {
-        setPrevEndRow((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setPrevEndRow((byte[])value);
+        } else {
+          setPrevEndRow((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case TABLE_ID:
       return getTableId();
@@ -319,13 +297,13 @@
       return getPrevEndRow();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -336,11 +314,11 @@
     case PREV_END_ROW:
       return isSetPrevEndRow();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof KeyExtent)
@@ -351,6 +329,8 @@
   public boolean equals(KeyExtent that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_tableId = true && this.isSetTableId();
     boolean that_present_tableId = true && that.isSetTableId();
@@ -384,24 +364,21 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_tableId = true && (isSetTableId());
-    list.add(present_tableId);
-    if (present_tableId)
-      list.add(tableId);
+    hashCode = hashCode * 8191 + ((isSetTableId()) ? 131071 : 524287);
+    if (isSetTableId())
+      hashCode = hashCode * 8191 + tableId.hashCode();
 
-    boolean present_endRow = true && (isSetEndRow());
-    list.add(present_endRow);
-    if (present_endRow)
-      list.add(endRow);
+    hashCode = hashCode * 8191 + ((isSetEndRow()) ? 131071 : 524287);
+    if (isSetEndRow())
+      hashCode = hashCode * 8191 + endRow.hashCode();
 
-    boolean present_prevEndRow = true && (isSetPrevEndRow());
-    list.add(present_prevEndRow);
-    if (present_prevEndRow)
-      list.add(prevEndRow);
+    hashCode = hashCode * 8191 + ((isSetPrevEndRow()) ? 131071 : 524287);
+    if (isSetPrevEndRow())
+      hashCode = hashCode * 8191 + prevEndRow.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -412,7 +389,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetTableId()).compareTo(other.isSetTableId());
+    lastComparison = java.lang.Boolean.valueOf(isSetTableId()).compareTo(other.isSetTableId());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -422,7 +399,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
+    lastComparison = java.lang.Boolean.valueOf(isSetEndRow()).compareTo(other.isSetEndRow());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -432,7 +409,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetPrevEndRow()).compareTo(other.isSetPrevEndRow());
+    lastComparison = java.lang.Boolean.valueOf(isSetPrevEndRow()).compareTo(other.isSetPrevEndRow());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -450,16 +427,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("KeyExtent(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("KeyExtent(");
     boolean first = true;
 
     sb.append("tableId:");
@@ -502,7 +479,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -510,13 +487,13 @@
     }
   }
 
-  private static class KeyExtentStandardSchemeFactory implements SchemeFactory {
+  private static class KeyExtentStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public KeyExtentStandardScheme getScheme() {
       return new KeyExtentStandardScheme();
     }
   }
 
-  private static class KeyExtentStandardScheme extends StandardScheme<KeyExtent> {
+  private static class KeyExtentStandardScheme extends org.apache.thrift.scheme.StandardScheme<KeyExtent> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, KeyExtent struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -588,18 +565,18 @@
 
   }
 
-  private static class KeyExtentTupleSchemeFactory implements SchemeFactory {
+  private static class KeyExtentTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public KeyExtentTupleScheme getScheme() {
       return new KeyExtentTupleScheme();
     }
   }
 
-  private static class KeyExtentTupleScheme extends TupleScheme<KeyExtent> {
+  private static class KeyExtentTupleScheme extends org.apache.thrift.scheme.TupleScheme<KeyExtent> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, KeyExtent struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetTableId()) {
         optionals.set(0);
       }
@@ -623,8 +600,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, KeyExtent struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(3);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(3);
       if (incoming.get(0)) {
         struct.tableId = iprot.readString();
         struct.setTableIdIsSet(true);
@@ -640,5 +617,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 480236c..0f87c09 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/KeyValue.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/KeyValue.java
@@ -15,66 +15,36 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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);
   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)2);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new KeyValueStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new KeyValueTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new KeyValueStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new KeyValueTupleSchemeFactory();
 
   public Key key; // required
-  public ByteBuffer value; // required
+  public java.nio.ByteBuffer 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 {
     KEY((short)1, "key"),
     VALUE((short)2, "value");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -99,21 +69,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -122,20 +92,20 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Key.class)));
     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        , true)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(KeyValue.class, metaDataMap);
   }
 
@@ -144,7 +114,7 @@
 
   public KeyValue(
     Key key,
-    ByteBuffer value)
+    java.nio.ByteBuffer value)
   {
     this();
     this.key = key;
@@ -202,16 +172,16 @@
     return value == null ? null : value.array();
   }
 
-  public ByteBuffer bufferForValue() {
+  public java.nio.ByteBuffer bufferForValue() {
     return org.apache.thrift.TBaseHelper.copyBinary(value);
   }
 
   public KeyValue setValue(byte[] value) {
-    this.value = value == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(value, value.length));
+    this.value = value == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(value.clone());
     return this;
   }
 
-  public KeyValue setValue(ByteBuffer value) {
+  public KeyValue setValue(java.nio.ByteBuffer value) {
     this.value = org.apache.thrift.TBaseHelper.copyBinary(value);
     return this;
   }
@@ -231,7 +201,7 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case KEY:
       if (value == null) {
@@ -245,14 +215,18 @@
       if (value == null) {
         unsetValue();
       } else {
-        setValue((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setValue((byte[])value);
+        } else {
+          setValue((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case KEY:
       return getKey();
@@ -261,13 +235,13 @@
       return getValue();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -276,11 +250,11 @@
     case VALUE:
       return isSetValue();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof KeyValue)
@@ -291,6 +265,8 @@
   public boolean equals(KeyValue that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_key = true && this.isSetKey();
     boolean that_present_key = true && that.isSetKey();
@@ -315,19 +291,17 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_key = true && (isSetKey());
-    list.add(present_key);
-    if (present_key)
-      list.add(key);
+    hashCode = hashCode * 8191 + ((isSetKey()) ? 131071 : 524287);
+    if (isSetKey())
+      hashCode = hashCode * 8191 + key.hashCode();
 
-    boolean present_value = true && (isSetValue());
-    list.add(present_value);
-    if (present_value)
-      list.add(value);
+    hashCode = hashCode * 8191 + ((isSetValue()) ? 131071 : 524287);
+    if (isSetValue())
+      hashCode = hashCode * 8191 + value.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -338,7 +312,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
+    lastComparison = java.lang.Boolean.valueOf(isSetKey()).compareTo(other.isSetKey());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -348,7 +322,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
+    lastComparison = java.lang.Boolean.valueOf(isSetValue()).compareTo(other.isSetValue());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -366,16 +340,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("KeyValue(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("KeyValue(");
     boolean first = true;
 
     sb.append("key:");
@@ -413,7 +387,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -421,13 +395,13 @@
     }
   }
 
-  private static class KeyValueStandardSchemeFactory implements SchemeFactory {
+  private static class KeyValueStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public KeyValueStandardScheme getScheme() {
       return new KeyValueStandardScheme();
     }
   }
 
-  private static class KeyValueStandardScheme extends StandardScheme<KeyValue> {
+  private static class KeyValueStandardScheme extends org.apache.thrift.scheme.StandardScheme<KeyValue> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, KeyValue struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -487,18 +461,18 @@
 
   }
 
-  private static class KeyValueTupleSchemeFactory implements SchemeFactory {
+  private static class KeyValueTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public KeyValueTupleScheme getScheme() {
       return new KeyValueTupleScheme();
     }
   }
 
-  private static class KeyValueTupleScheme extends TupleScheme<KeyValue> {
+  private static class KeyValueTupleScheme extends org.apache.thrift.scheme.TupleScheme<KeyValue> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, KeyValue struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetKey()) {
         optionals.set(0);
       }
@@ -516,8 +490,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, KeyValue struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(2);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(2);
       if (incoming.get(0)) {
         struct.key = new Key();
         struct.key.read(iprot);
@@ -530,5 +504,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 3bb4f13..2d121da 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/KeyValueAndPeek.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/KeyValueAndPeek.java
@@ -15,53 +15,23 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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);
   private static final org.apache.thrift.protocol.TField HAS_NEXT_FIELD_DESC = new org.apache.thrift.protocol.TField("hasNext", org.apache.thrift.protocol.TType.BOOL, (short)2);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new KeyValueAndPeekStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new KeyValueAndPeekTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new KeyValueAndPeekStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new KeyValueAndPeekTupleSchemeFactory();
 
   public KeyValue keyValue; // required
   public boolean hasNext; // required
@@ -71,10 +41,10 @@
     KEY_VALUE((short)1, "keyValue"),
     HAS_NEXT((short)2, "hasNext");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -99,21 +69,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -122,7 +92,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -130,14 +100,14 @@
   // isset id assignments
   private static final int __HASNEXT_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.KEY_VALUE, new org.apache.thrift.meta_data.FieldMetaData("keyValue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KeyValue.class)));
     tmpMap.put(_Fields.HAS_NEXT, new org.apache.thrift.meta_data.FieldMetaData("hasNext", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(KeyValueAndPeek.class, metaDataMap);
   }
 
@@ -211,19 +181,19 @@
   }
 
   public void unsetHasNext() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __HASNEXT_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __HASNEXT_ISSET_ID);
   }
 
   /** Returns true if field hasNext is set (has been assigned a value) and false otherwise */
   public boolean isSetHasNext() {
-    return EncodingUtils.testBit(__isset_bitfield, __HASNEXT_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __HASNEXT_ISSET_ID);
   }
 
   public void setHasNextIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __HASNEXT_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __HASNEXT_ISSET_ID, value);
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case KEY_VALUE:
       if (value == null) {
@@ -237,14 +207,14 @@
       if (value == null) {
         unsetHasNext();
       } else {
-        setHasNext((Boolean)value);
+        setHasNext((java.lang.Boolean)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case KEY_VALUE:
       return getKeyValue();
@@ -253,13 +223,13 @@
       return isHasNext();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -268,11 +238,11 @@
     case HAS_NEXT:
       return isSetHasNext();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof KeyValueAndPeek)
@@ -283,6 +253,8 @@
   public boolean equals(KeyValueAndPeek that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_keyValue = true && this.isSetKeyValue();
     boolean that_present_keyValue = true && that.isSetKeyValue();
@@ -307,19 +279,15 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_keyValue = true && (isSetKeyValue());
-    list.add(present_keyValue);
-    if (present_keyValue)
-      list.add(keyValue);
+    hashCode = hashCode * 8191 + ((isSetKeyValue()) ? 131071 : 524287);
+    if (isSetKeyValue())
+      hashCode = hashCode * 8191 + keyValue.hashCode();
 
-    boolean present_hasNext = true;
-    list.add(present_hasNext);
-    if (present_hasNext)
-      list.add(hasNext);
+    hashCode = hashCode * 8191 + ((hasNext) ? 131071 : 524287);
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -330,7 +298,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetKeyValue()).compareTo(other.isSetKeyValue());
+    lastComparison = java.lang.Boolean.valueOf(isSetKeyValue()).compareTo(other.isSetKeyValue());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -340,7 +308,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetHasNext()).compareTo(other.isSetHasNext());
+    lastComparison = java.lang.Boolean.valueOf(isSetHasNext()).compareTo(other.isSetHasNext());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -358,16 +326,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("KeyValueAndPeek(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("KeyValueAndPeek(");
     boolean first = true;
 
     sb.append("keyValue:");
@@ -401,7 +369,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -411,13 +379,13 @@
     }
   }
 
-  private static class KeyValueAndPeekStandardSchemeFactory implements SchemeFactory {
+  private static class KeyValueAndPeekStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public KeyValueAndPeekStandardScheme getScheme() {
       return new KeyValueAndPeekStandardScheme();
     }
   }
 
-  private static class KeyValueAndPeekStandardScheme extends StandardScheme<KeyValueAndPeek> {
+  private static class KeyValueAndPeekStandardScheme extends org.apache.thrift.scheme.StandardScheme<KeyValueAndPeek> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, KeyValueAndPeek struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -475,18 +443,18 @@
 
   }
 
-  private static class KeyValueAndPeekTupleSchemeFactory implements SchemeFactory {
+  private static class KeyValueAndPeekTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public KeyValueAndPeekTupleScheme getScheme() {
       return new KeyValueAndPeekTupleScheme();
     }
   }
 
-  private static class KeyValueAndPeekTupleScheme extends TupleScheme<KeyValueAndPeek> {
+  private static class KeyValueAndPeekTupleScheme extends org.apache.thrift.scheme.TupleScheme<KeyValueAndPeek> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, KeyValueAndPeek struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetKeyValue()) {
         optionals.set(0);
       }
@@ -504,8 +472,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, KeyValueAndPeek struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(2);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(2);
       if (incoming.get(0)) {
         struct.keyValue = new KeyValue();
         struct.keyValue.read(iprot);
@@ -518,5 +486,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 db5b6c4..c1532ba 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/MutationsRejectedException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/MutationsRejectedException.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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 MutationsRejectedException extends TException implements org.apache.thrift.TBase<MutationsRejectedException, MutationsRejectedException._Fields>, java.io.Serializable, Cloneable, Comparable<MutationsRejectedException> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class MutationsRejectedException extends org.apache.thrift.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);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new MutationsRejectedExceptionStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new MutationsRejectedExceptionTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new MutationsRejectedExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new MutationsRejectedExceptionTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(MutationsRejectedException.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public MutationsRejectedException(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public MutationsRejectedException setMsg(String msg) {
+  public MutationsRejectedException setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof MutationsRejectedException)
@@ -231,6 +201,8 @@
   public boolean equals(MutationsRejectedException that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("MutationsRejectedException(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("MutationsRejectedException(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class MutationsRejectedExceptionStandardSchemeFactory implements SchemeFactory {
+  private static class MutationsRejectedExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public MutationsRejectedExceptionStandardScheme getScheme() {
       return new MutationsRejectedExceptionStandardScheme();
     }
   }
 
-  private static class MutationsRejectedExceptionStandardScheme extends StandardScheme<MutationsRejectedException> {
+  private static class MutationsRejectedExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<MutationsRejectedException> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, MutationsRejectedException struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class MutationsRejectedExceptionTupleSchemeFactory implements SchemeFactory {
+  private static class MutationsRejectedExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public MutationsRejectedExceptionTupleScheme getScheme() {
       return new MutationsRejectedExceptionTupleScheme();
     }
   }
 
-  private static class MutationsRejectedExceptionTupleScheme extends TupleScheme<MutationsRejectedException> {
+  private static class MutationsRejectedExceptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<MutationsRejectedException> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, MutationsRejectedException struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, MutationsRejectedException struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(1);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceExistsException.java b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceExistsException.java
index db1a380..a8148d2 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceExistsException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceExistsException.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class NamespaceExistsException extends org.apache.thrift.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());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new NamespaceExistsExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new NamespaceExistsExceptionTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(NamespaceExistsException.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public NamespaceExistsException(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public NamespaceExistsException setMsg(String msg) {
+  public NamespaceExistsException setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof NamespaceExistsException)
@@ -231,6 +201,8 @@
   public boolean equals(NamespaceExistsException that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("NamespaceExistsException(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("NamespaceExistsException(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class NamespaceExistsExceptionStandardSchemeFactory implements SchemeFactory {
+  private static class NamespaceExistsExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public NamespaceExistsExceptionStandardScheme getScheme() {
       return new NamespaceExistsExceptionStandardScheme();
     }
   }
 
-  private static class NamespaceExistsExceptionStandardScheme extends StandardScheme<NamespaceExistsException> {
+  private static class NamespaceExistsExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<NamespaceExistsException> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, NamespaceExistsException struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class NamespaceExistsExceptionTupleSchemeFactory implements SchemeFactory {
+  private static class NamespaceExistsExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public NamespaceExistsExceptionTupleScheme getScheme() {
       return new NamespaceExistsExceptionTupleScheme();
     }
   }
 
-  private static class NamespaceExistsExceptionTupleScheme extends TupleScheme<NamespaceExistsException> {
+  private static class NamespaceExistsExceptionTupleScheme extends org.apache.thrift.scheme.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();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @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);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotEmptyException.java b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotEmptyException.java
index f22320e..1927347 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotEmptyException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotEmptyException.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class NamespaceNotEmptyException extends org.apache.thrift.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());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new NamespaceNotEmptyExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new NamespaceNotEmptyExceptionTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(NamespaceNotEmptyException.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public NamespaceNotEmptyException(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public NamespaceNotEmptyException setMsg(String msg) {
+  public NamespaceNotEmptyException setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof NamespaceNotEmptyException)
@@ -231,6 +201,8 @@
   public boolean equals(NamespaceNotEmptyException that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("NamespaceNotEmptyException(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("NamespaceNotEmptyException(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class NamespaceNotEmptyExceptionStandardSchemeFactory implements SchemeFactory {
+  private static class NamespaceNotEmptyExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public NamespaceNotEmptyExceptionStandardScheme getScheme() {
       return new NamespaceNotEmptyExceptionStandardScheme();
     }
   }
 
-  private static class NamespaceNotEmptyExceptionStandardScheme extends StandardScheme<NamespaceNotEmptyException> {
+  private static class NamespaceNotEmptyExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<NamespaceNotEmptyException> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, NamespaceNotEmptyException struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class NamespaceNotEmptyExceptionTupleSchemeFactory implements SchemeFactory {
+  private static class NamespaceNotEmptyExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public NamespaceNotEmptyExceptionTupleScheme getScheme() {
       return new NamespaceNotEmptyExceptionTupleScheme();
     }
   }
 
-  private static class NamespaceNotEmptyExceptionTupleScheme extends TupleScheme<NamespaceNotEmptyException> {
+  private static class NamespaceNotEmptyExceptionTupleScheme extends org.apache.thrift.scheme.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();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @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);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotFoundException.java b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotFoundException.java
index 9e31e48..894e0af 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotFoundException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/NamespaceNotFoundException.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class NamespaceNotFoundException extends org.apache.thrift.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());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new NamespaceNotFoundExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new NamespaceNotFoundExceptionTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(NamespaceNotFoundException.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public NamespaceNotFoundException(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public NamespaceNotFoundException setMsg(String msg) {
+  public NamespaceNotFoundException setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof NamespaceNotFoundException)
@@ -231,6 +201,8 @@
   public boolean equals(NamespaceNotFoundException that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("NamespaceNotFoundException(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("NamespaceNotFoundException(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class NamespaceNotFoundExceptionStandardSchemeFactory implements SchemeFactory {
+  private static class NamespaceNotFoundExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public NamespaceNotFoundExceptionStandardScheme getScheme() {
       return new NamespaceNotFoundExceptionStandardScheme();
     }
   }
 
-  private static class NamespaceNotFoundExceptionStandardScheme extends StandardScheme<NamespaceNotFoundException> {
+  private static class NamespaceNotFoundExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<NamespaceNotFoundException> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, NamespaceNotFoundException struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class NamespaceNotFoundExceptionTupleSchemeFactory implements SchemeFactory {
+  private static class NamespaceNotFoundExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public NamespaceNotFoundExceptionTupleScheme getScheme() {
       return new NamespaceNotFoundExceptionTupleScheme();
     }
   }
 
-  private static class NamespaceNotFoundExceptionTupleScheme extends TupleScheme<NamespaceNotFoundException> {
+  private static class NamespaceNotFoundExceptionTupleScheme extends org.apache.thrift.scheme.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();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @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);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
diff --git a/src/main/java/org/apache/accumulo/proxy/thrift/NamespacePermission.java b/src/main/java/org/apache/accumulo/proxy/thrift/NamespacePermission.java
index 6d790f6..9a831a4 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/NamespacePermission.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/NamespacePermission.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 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 {
+public enum NamespacePermission implements org.apache.thrift.TEnum {
   READ(0),
   WRITE(1),
   ALTER_NAMESPACE(2),
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 182277a..f28e747 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/NoMoreEntriesException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/NoMoreEntriesException.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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 NoMoreEntriesException extends TException implements org.apache.thrift.TBase<NoMoreEntriesException, NoMoreEntriesException._Fields>, java.io.Serializable, Cloneable, Comparable<NoMoreEntriesException> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class NoMoreEntriesException extends org.apache.thrift.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);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new NoMoreEntriesExceptionStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new NoMoreEntriesExceptionTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new NoMoreEntriesExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new NoMoreEntriesExceptionTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(NoMoreEntriesException.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public NoMoreEntriesException(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public NoMoreEntriesException setMsg(String msg) {
+  public NoMoreEntriesException setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof NoMoreEntriesException)
@@ -231,6 +201,8 @@
   public boolean equals(NoMoreEntriesException that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("NoMoreEntriesException(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("NoMoreEntriesException(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class NoMoreEntriesExceptionStandardSchemeFactory implements SchemeFactory {
+  private static class NoMoreEntriesExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public NoMoreEntriesExceptionStandardScheme getScheme() {
       return new NoMoreEntriesExceptionStandardScheme();
     }
   }
 
-  private static class NoMoreEntriesExceptionStandardScheme extends StandardScheme<NoMoreEntriesException> {
+  private static class NoMoreEntriesExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<NoMoreEntriesException> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, NoMoreEntriesException struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class NoMoreEntriesExceptionTupleSchemeFactory implements SchemeFactory {
+  private static class NoMoreEntriesExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public NoMoreEntriesExceptionTupleScheme getScheme() {
       return new NoMoreEntriesExceptionTupleScheme();
     }
   }
 
-  private static class NoMoreEntriesExceptionTupleScheme extends TupleScheme<NoMoreEntriesException> {
+  private static class NoMoreEntriesExceptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<NoMoreEntriesException> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, NoMoreEntriesException struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, NoMoreEntriesException struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(1);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 b03eae9..11be665 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum PartialKey implements org.apache.thrift.TEnum {
+public enum PartialKey implements org.apache.thrift.TEnum {
   ROW(0),
   ROW_COLFAM(1),
   ROW_COLFAM_COLQUAL(2),
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 db8fe8e..92c6172 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/Range.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/Range.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -59,11 +32,8 @@
   private static final org.apache.thrift.protocol.TField STOP_FIELD_DESC = new org.apache.thrift.protocol.TField("stop", org.apache.thrift.protocol.TType.STRUCT, (short)3);
   private static final org.apache.thrift.protocol.TField STOP_INCLUSIVE_FIELD_DESC = new org.apache.thrift.protocol.TField("stopInclusive", org.apache.thrift.protocol.TType.BOOL, (short)4);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new RangeStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new RangeTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new RangeStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new RangeTupleSchemeFactory();
 
   public Key start; // required
   public boolean startInclusive; // required
@@ -77,10 +47,10 @@
     STOP((short)3, "stop"),
     STOP_INCLUSIVE((short)4, "stopInclusive");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -109,21 +79,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -132,7 +102,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -141,9 +111,9 @@
   private static final int __STARTINCLUSIVE_ISSET_ID = 0;
   private static final int __STOPINCLUSIVE_ISSET_ID = 1;
   private byte __isset_bitfield = 0;
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.START, new org.apache.thrift.meta_data.FieldMetaData("start", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Key.class)));
     tmpMap.put(_Fields.START_INCLUSIVE, new org.apache.thrift.meta_data.FieldMetaData("startInclusive", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -152,7 +122,7 @@
         new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Key.class)));
     tmpMap.put(_Fields.STOP_INCLUSIVE, new org.apache.thrift.meta_data.FieldMetaData("stopInclusive", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Range.class, metaDataMap);
   }
 
@@ -238,16 +208,16 @@
   }
 
   public void unsetStartInclusive() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID);
   }
 
   /** Returns true if field startInclusive is set (has been assigned a value) and false otherwise */
   public boolean isSetStartInclusive() {
-    return EncodingUtils.testBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID);
   }
 
   public void setStartInclusiveIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __STARTINCLUSIVE_ISSET_ID, value);
   }
 
   public Key getStop() {
@@ -285,19 +255,19 @@
   }
 
   public void unsetStopInclusive() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STOPINCLUSIVE_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __STOPINCLUSIVE_ISSET_ID);
   }
 
   /** Returns true if field stopInclusive is set (has been assigned a value) and false otherwise */
   public boolean isSetStopInclusive() {
-    return EncodingUtils.testBit(__isset_bitfield, __STOPINCLUSIVE_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __STOPINCLUSIVE_ISSET_ID);
   }
 
   public void setStopInclusiveIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STOPINCLUSIVE_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __STOPINCLUSIVE_ISSET_ID, value);
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case START:
       if (value == null) {
@@ -311,7 +281,7 @@
       if (value == null) {
         unsetStartInclusive();
       } else {
-        setStartInclusive((Boolean)value);
+        setStartInclusive((java.lang.Boolean)value);
       }
       break;
 
@@ -327,14 +297,14 @@
       if (value == null) {
         unsetStopInclusive();
       } else {
-        setStopInclusive((Boolean)value);
+        setStopInclusive((java.lang.Boolean)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case START:
       return getStart();
@@ -349,13 +319,13 @@
       return isStopInclusive();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -368,11 +338,11 @@
     case STOP_INCLUSIVE:
       return isSetStopInclusive();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof Range)
@@ -383,6 +353,8 @@
   public boolean equals(Range that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_start = true && this.isSetStart();
     boolean that_present_start = true && that.isSetStart();
@@ -425,29 +397,21 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_start = true && (isSetStart());
-    list.add(present_start);
-    if (present_start)
-      list.add(start);
+    hashCode = hashCode * 8191 + ((isSetStart()) ? 131071 : 524287);
+    if (isSetStart())
+      hashCode = hashCode * 8191 + start.hashCode();
 
-    boolean present_startInclusive = true;
-    list.add(present_startInclusive);
-    if (present_startInclusive)
-      list.add(startInclusive);
+    hashCode = hashCode * 8191 + ((startInclusive) ? 131071 : 524287);
 
-    boolean present_stop = true && (isSetStop());
-    list.add(present_stop);
-    if (present_stop)
-      list.add(stop);
+    hashCode = hashCode * 8191 + ((isSetStop()) ? 131071 : 524287);
+    if (isSetStop())
+      hashCode = hashCode * 8191 + stop.hashCode();
 
-    boolean present_stopInclusive = true;
-    list.add(present_stopInclusive);
-    if (present_stopInclusive)
-      list.add(stopInclusive);
+    hashCode = hashCode * 8191 + ((stopInclusive) ? 131071 : 524287);
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -458,7 +422,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetStart()).compareTo(other.isSetStart());
+    lastComparison = java.lang.Boolean.valueOf(isSetStart()).compareTo(other.isSetStart());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -468,7 +432,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetStartInclusive()).compareTo(other.isSetStartInclusive());
+    lastComparison = java.lang.Boolean.valueOf(isSetStartInclusive()).compareTo(other.isSetStartInclusive());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -478,7 +442,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetStop()).compareTo(other.isSetStop());
+    lastComparison = java.lang.Boolean.valueOf(isSetStop()).compareTo(other.isSetStop());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -488,7 +452,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetStopInclusive()).compareTo(other.isSetStopInclusive());
+    lastComparison = java.lang.Boolean.valueOf(isSetStopInclusive()).compareTo(other.isSetStopInclusive());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -506,16 +470,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("Range(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("Range(");
     boolean first = true;
 
     sb.append("start:");
@@ -564,7 +528,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -574,13 +538,13 @@
     }
   }
 
-  private static class RangeStandardSchemeFactory implements SchemeFactory {
+  private static class RangeStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public RangeStandardScheme getScheme() {
       return new RangeStandardScheme();
     }
   }
 
-  private static class RangeStandardScheme extends StandardScheme<Range> {
+  private static class RangeStandardScheme extends org.apache.thrift.scheme.StandardScheme<Range> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, Range struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -663,18 +627,18 @@
 
   }
 
-  private static class RangeTupleSchemeFactory implements SchemeFactory {
+  private static class RangeTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public RangeTupleScheme getScheme() {
       return new RangeTupleScheme();
     }
   }
 
-  private static class RangeTupleScheme extends TupleScheme<Range> {
+  private static class RangeTupleScheme extends org.apache.thrift.scheme.TupleScheme<Range> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, Range struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetStart()) {
         optionals.set(0);
       }
@@ -704,8 +668,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, Range struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(4);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(4);
       if (incoming.get(0)) {
         struct.start = new Key();
         struct.start.read(iprot);
@@ -727,5 +691,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 3cea424..1eb2b48 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ScanColumn.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ScanColumn.java
@@ -15,66 +15,36 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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);
   private static final org.apache.thrift.protocol.TField COL_QUALIFIER_FIELD_DESC = new org.apache.thrift.protocol.TField("colQualifier", 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 ScanColumnStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new ScanColumnTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ScanColumnStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ScanColumnTupleSchemeFactory();
 
-  public ByteBuffer colFamily; // required
-  public ByteBuffer colQualifier; // optional
+  public java.nio.ByteBuffer colFamily; // required
+  public java.nio.ByteBuffer colQualifier; // optional
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
   public enum _Fields implements org.apache.thrift.TFieldIdEnum {
     COL_FAMILY((short)1, "colFamily"),
     COL_QUALIFIER((short)2, "colQualifier");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -99,21 +69,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -122,21 +92,21 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
   private static final _Fields optionals[] = {_Fields.COL_QUALIFIER};
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.COL_FAMILY, new org.apache.thrift.meta_data.FieldMetaData("colFamily", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
     tmpMap.put(_Fields.COL_QUALIFIER, new org.apache.thrift.meta_data.FieldMetaData("colQualifier", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ScanColumn.class, metaDataMap);
   }
 
@@ -144,7 +114,7 @@
   }
 
   public ScanColumn(
-    ByteBuffer colFamily)
+    java.nio.ByteBuffer colFamily)
   {
     this();
     this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
@@ -177,16 +147,16 @@
     return colFamily == null ? null : colFamily.array();
   }
 
-  public ByteBuffer bufferForColFamily() {
+  public java.nio.ByteBuffer bufferForColFamily() {
     return org.apache.thrift.TBaseHelper.copyBinary(colFamily);
   }
 
   public ScanColumn setColFamily(byte[] colFamily) {
-    this.colFamily = colFamily == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colFamily, colFamily.length));
+    this.colFamily = colFamily == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colFamily.clone());
     return this;
   }
 
-  public ScanColumn setColFamily(ByteBuffer colFamily) {
+  public ScanColumn setColFamily(java.nio.ByteBuffer colFamily) {
     this.colFamily = org.apache.thrift.TBaseHelper.copyBinary(colFamily);
     return this;
   }
@@ -211,16 +181,16 @@
     return colQualifier == null ? null : colQualifier.array();
   }
 
-  public ByteBuffer bufferForColQualifier() {
+  public java.nio.ByteBuffer bufferForColQualifier() {
     return org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
   }
 
   public ScanColumn setColQualifier(byte[] colQualifier) {
-    this.colQualifier = colQualifier == null ? (ByteBuffer)null : ByteBuffer.wrap(Arrays.copyOf(colQualifier, colQualifier.length));
+    this.colQualifier = colQualifier == null ? (java.nio.ByteBuffer)null : java.nio.ByteBuffer.wrap(colQualifier.clone());
     return this;
   }
 
-  public ScanColumn setColQualifier(ByteBuffer colQualifier) {
+  public ScanColumn setColQualifier(java.nio.ByteBuffer colQualifier) {
     this.colQualifier = org.apache.thrift.TBaseHelper.copyBinary(colQualifier);
     return this;
   }
@@ -240,13 +210,17 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case COL_FAMILY:
       if (value == null) {
         unsetColFamily();
       } else {
-        setColFamily((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColFamily((byte[])value);
+        } else {
+          setColFamily((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
@@ -254,14 +228,18 @@
       if (value == null) {
         unsetColQualifier();
       } else {
-        setColQualifier((ByteBuffer)value);
+        if (value instanceof byte[]) {
+          setColQualifier((byte[])value);
+        } else {
+          setColQualifier((java.nio.ByteBuffer)value);
+        }
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case COL_FAMILY:
       return getColFamily();
@@ -270,13 +248,13 @@
       return getColQualifier();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -285,11 +263,11 @@
     case COL_QUALIFIER:
       return isSetColQualifier();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof ScanColumn)
@@ -300,6 +278,8 @@
   public boolean equals(ScanColumn that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_colFamily = true && this.isSetColFamily();
     boolean that_present_colFamily = true && that.isSetColFamily();
@@ -324,19 +304,17 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_colFamily = true && (isSetColFamily());
-    list.add(present_colFamily);
-    if (present_colFamily)
-      list.add(colFamily);
+    hashCode = hashCode * 8191 + ((isSetColFamily()) ? 131071 : 524287);
+    if (isSetColFamily())
+      hashCode = hashCode * 8191 + colFamily.hashCode();
 
-    boolean present_colQualifier = true && (isSetColQualifier());
-    list.add(present_colQualifier);
-    if (present_colQualifier)
-      list.add(colQualifier);
+    hashCode = hashCode * 8191 + ((isSetColQualifier()) ? 131071 : 524287);
+    if (isSetColQualifier())
+      hashCode = hashCode * 8191 + colQualifier.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -347,7 +325,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetColFamily()).compareTo(other.isSetColFamily());
+    lastComparison = java.lang.Boolean.valueOf(isSetColFamily()).compareTo(other.isSetColFamily());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -357,7 +335,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColQualifier()).compareTo(other.isSetColQualifier());
+    lastComparison = java.lang.Boolean.valueOf(isSetColQualifier()).compareTo(other.isSetColQualifier());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -375,16 +353,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("ScanColumn(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("ScanColumn(");
     boolean first = true;
 
     sb.append("colFamily:");
@@ -421,7 +399,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -429,13 +407,13 @@
     }
   }
 
-  private static class ScanColumnStandardSchemeFactory implements SchemeFactory {
+  private static class ScanColumnStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ScanColumnStandardScheme getScheme() {
       return new ScanColumnStandardScheme();
     }
   }
 
-  private static class ScanColumnStandardScheme extends StandardScheme<ScanColumn> {
+  private static class ScanColumnStandardScheme extends org.apache.thrift.scheme.StandardScheme<ScanColumn> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, ScanColumn struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -496,18 +474,18 @@
 
   }
 
-  private static class ScanColumnTupleSchemeFactory implements SchemeFactory {
+  private static class ScanColumnTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ScanColumnTupleScheme getScheme() {
       return new ScanColumnTupleScheme();
     }
   }
 
-  private static class ScanColumnTupleScheme extends TupleScheme<ScanColumn> {
+  private static class ScanColumnTupleScheme extends org.apache.thrift.scheme.TupleScheme<ScanColumn> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, ScanColumn struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetColFamily()) {
         optionals.set(0);
       }
@@ -525,8 +503,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, ScanColumn struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(2);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(2);
       if (incoming.get(0)) {
         struct.colFamily = iprot.readBinary();
         struct.setColFamilyIsSet(true);
@@ -538,5 +516,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 6675c8e..08224f9 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ScanOptions.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ScanOptions.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -60,16 +33,13 @@
   private static final org.apache.thrift.protocol.TField ITERATORS_FIELD_DESC = new org.apache.thrift.protocol.TField("iterators", org.apache.thrift.protocol.TType.LIST, (short)4);
   private static final org.apache.thrift.protocol.TField BUFFER_SIZE_FIELD_DESC = new org.apache.thrift.protocol.TField("bufferSize", org.apache.thrift.protocol.TType.I32, (short)5);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new ScanOptionsStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new ScanOptionsTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ScanOptionsStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ScanOptionsTupleSchemeFactory();
 
-  public Set<ByteBuffer> authorizations; // optional
+  public java.util.Set<java.nio.ByteBuffer> authorizations; // optional
   public Range range; // optional
-  public List<ScanColumn> columns; // optional
-  public List<IteratorSetting> iterators; // optional
+  public java.util.List<ScanColumn> columns; // optional
+  public java.util.List<IteratorSetting> iterators; // optional
   public int bufferSize; // optional
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -80,10 +50,10 @@
     ITERATORS((short)4, "iterators"),
     BUFFER_SIZE((short)5, "bufferSize");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -114,21 +84,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -137,7 +107,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -146,9 +116,9 @@
   private static final int __BUFFERSIZE_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
   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;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.AUTHORIZATIONS, new org.apache.thrift.meta_data.FieldMetaData("authorizations", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
             new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING            , true))));
@@ -162,7 +132,7 @@
             new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, IteratorSetting.class))));
     tmpMap.put(_Fields.BUFFER_SIZE, new org.apache.thrift.meta_data.FieldMetaData("bufferSize", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ScanOptions.class, metaDataMap);
   }
 
@@ -175,21 +145,21 @@
   public ScanOptions(ScanOptions other) {
     __isset_bitfield = other.__isset_bitfield;
     if (other.isSetAuthorizations()) {
-      Set<ByteBuffer> __this__authorizations = new HashSet<ByteBuffer>(other.authorizations);
+      java.util.Set<java.nio.ByteBuffer> __this__authorizations = new java.util.HashSet<java.nio.ByteBuffer>(other.authorizations);
       this.authorizations = __this__authorizations;
     }
     if (other.isSetRange()) {
       this.range = new Range(other.range);
     }
     if (other.isSetColumns()) {
-      List<ScanColumn> __this__columns = new ArrayList<ScanColumn>(other.columns.size());
+      java.util.List<ScanColumn> __this__columns = new java.util.ArrayList<ScanColumn>(other.columns.size());
       for (ScanColumn other_element : other.columns) {
         __this__columns.add(new ScanColumn(other_element));
       }
       this.columns = __this__columns;
     }
     if (other.isSetIterators()) {
-      List<IteratorSetting> __this__iterators = new ArrayList<IteratorSetting>(other.iterators.size());
+      java.util.List<IteratorSetting> __this__iterators = new java.util.ArrayList<IteratorSetting>(other.iterators.size());
       for (IteratorSetting other_element : other.iterators) {
         __this__iterators.add(new IteratorSetting(other_element));
       }
@@ -216,22 +186,22 @@
     return (this.authorizations == null) ? 0 : this.authorizations.size();
   }
 
-  public java.util.Iterator<ByteBuffer> getAuthorizationsIterator() {
+  public java.util.Iterator<java.nio.ByteBuffer> getAuthorizationsIterator() {
     return (this.authorizations == null) ? null : this.authorizations.iterator();
   }
 
-  public void addToAuthorizations(ByteBuffer elem) {
+  public void addToAuthorizations(java.nio.ByteBuffer elem) {
     if (this.authorizations == null) {
-      this.authorizations = new HashSet<ByteBuffer>();
+      this.authorizations = new java.util.HashSet<java.nio.ByteBuffer>();
     }
     this.authorizations.add(elem);
   }
 
-  public Set<ByteBuffer> getAuthorizations() {
+  public java.util.Set<java.nio.ByteBuffer> getAuthorizations() {
     return this.authorizations;
   }
 
-  public ScanOptions setAuthorizations(Set<ByteBuffer> authorizations) {
+  public ScanOptions setAuthorizations(java.util.Set<java.nio.ByteBuffer> authorizations) {
     this.authorizations = authorizations;
     return this;
   }
@@ -285,16 +255,16 @@
 
   public void addToColumns(ScanColumn elem) {
     if (this.columns == null) {
-      this.columns = new ArrayList<ScanColumn>();
+      this.columns = new java.util.ArrayList<ScanColumn>();
     }
     this.columns.add(elem);
   }
 
-  public List<ScanColumn> getColumns() {
+  public java.util.List<ScanColumn> getColumns() {
     return this.columns;
   }
 
-  public ScanOptions setColumns(List<ScanColumn> columns) {
+  public ScanOptions setColumns(java.util.List<ScanColumn> columns) {
     this.columns = columns;
     return this;
   }
@@ -324,16 +294,16 @@
 
   public void addToIterators(IteratorSetting elem) {
     if (this.iterators == null) {
-      this.iterators = new ArrayList<IteratorSetting>();
+      this.iterators = new java.util.ArrayList<IteratorSetting>();
     }
     this.iterators.add(elem);
   }
 
-  public List<IteratorSetting> getIterators() {
+  public java.util.List<IteratorSetting> getIterators() {
     return this.iterators;
   }
 
-  public ScanOptions setIterators(List<IteratorSetting> iterators) {
+  public ScanOptions setIterators(java.util.List<IteratorSetting> iterators) {
     this.iterators = iterators;
     return this;
   }
@@ -364,25 +334,25 @@
   }
 
   public void unsetBufferSize() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __BUFFERSIZE_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __BUFFERSIZE_ISSET_ID);
   }
 
   /** Returns true if field bufferSize is set (has been assigned a value) and false otherwise */
   public boolean isSetBufferSize() {
-    return EncodingUtils.testBit(__isset_bitfield, __BUFFERSIZE_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __BUFFERSIZE_ISSET_ID);
   }
 
   public void setBufferSizeIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __BUFFERSIZE_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __BUFFERSIZE_ISSET_ID, value);
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case AUTHORIZATIONS:
       if (value == null) {
         unsetAuthorizations();
       } else {
-        setAuthorizations((Set<ByteBuffer>)value);
+        setAuthorizations((java.util.Set<java.nio.ByteBuffer>)value);
       }
       break;
 
@@ -398,7 +368,7 @@
       if (value == null) {
         unsetColumns();
       } else {
-        setColumns((List<ScanColumn>)value);
+        setColumns((java.util.List<ScanColumn>)value);
       }
       break;
 
@@ -406,7 +376,7 @@
       if (value == null) {
         unsetIterators();
       } else {
-        setIterators((List<IteratorSetting>)value);
+        setIterators((java.util.List<IteratorSetting>)value);
       }
       break;
 
@@ -414,14 +384,14 @@
       if (value == null) {
         unsetBufferSize();
       } else {
-        setBufferSize((Integer)value);
+        setBufferSize((java.lang.Integer)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case AUTHORIZATIONS:
       return getAuthorizations();
@@ -439,13 +409,13 @@
       return getBufferSize();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -460,11 +430,11 @@
     case BUFFER_SIZE:
       return isSetBufferSize();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof ScanOptions)
@@ -475,6 +445,8 @@
   public boolean equals(ScanOptions that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_authorizations = true && this.isSetAuthorizations();
     boolean that_present_authorizations = true && that.isSetAuthorizations();
@@ -526,34 +498,29 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_authorizations = true && (isSetAuthorizations());
-    list.add(present_authorizations);
-    if (present_authorizations)
-      list.add(authorizations);
+    hashCode = hashCode * 8191 + ((isSetAuthorizations()) ? 131071 : 524287);
+    if (isSetAuthorizations())
+      hashCode = hashCode * 8191 + authorizations.hashCode();
 
-    boolean present_range = true && (isSetRange());
-    list.add(present_range);
-    if (present_range)
-      list.add(range);
+    hashCode = hashCode * 8191 + ((isSetRange()) ? 131071 : 524287);
+    if (isSetRange())
+      hashCode = hashCode * 8191 + range.hashCode();
 
-    boolean present_columns = true && (isSetColumns());
-    list.add(present_columns);
-    if (present_columns)
-      list.add(columns);
+    hashCode = hashCode * 8191 + ((isSetColumns()) ? 131071 : 524287);
+    if (isSetColumns())
+      hashCode = hashCode * 8191 + columns.hashCode();
 
-    boolean present_iterators = true && (isSetIterators());
-    list.add(present_iterators);
-    if (present_iterators)
-      list.add(iterators);
+    hashCode = hashCode * 8191 + ((isSetIterators()) ? 131071 : 524287);
+    if (isSetIterators())
+      hashCode = hashCode * 8191 + iterators.hashCode();
 
-    boolean present_bufferSize = true && (isSetBufferSize());
-    list.add(present_bufferSize);
-    if (present_bufferSize)
-      list.add(bufferSize);
+    hashCode = hashCode * 8191 + ((isSetBufferSize()) ? 131071 : 524287);
+    if (isSetBufferSize())
+      hashCode = hashCode * 8191 + bufferSize;
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -564,7 +531,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
+    lastComparison = java.lang.Boolean.valueOf(isSetAuthorizations()).compareTo(other.isSetAuthorizations());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -574,7 +541,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetRange()).compareTo(other.isSetRange());
+    lastComparison = java.lang.Boolean.valueOf(isSetRange()).compareTo(other.isSetRange());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -584,7 +551,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetColumns()).compareTo(other.isSetColumns());
+    lastComparison = java.lang.Boolean.valueOf(isSetColumns()).compareTo(other.isSetColumns());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -594,7 +561,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
+    lastComparison = java.lang.Boolean.valueOf(isSetIterators()).compareTo(other.isSetIterators());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -604,7 +571,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetBufferSize()).compareTo(other.isSetBufferSize());
+    lastComparison = java.lang.Boolean.valueOf(isSetBufferSize()).compareTo(other.isSetBufferSize());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -622,16 +589,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("ScanOptions(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("ScanOptions(");
     boolean first = true;
 
     if (isSetAuthorizations()) {
@@ -699,7 +666,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -709,13 +676,13 @@
     }
   }
 
-  private static class ScanOptionsStandardSchemeFactory implements SchemeFactory {
+  private static class ScanOptionsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ScanOptionsStandardScheme getScheme() {
       return new ScanOptionsStandardScheme();
     }
   }
 
-  private static class ScanOptionsStandardScheme extends StandardScheme<ScanOptions> {
+  private static class ScanOptionsStandardScheme extends org.apache.thrift.scheme.StandardScheme<ScanOptions> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, ScanOptions struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -731,8 +698,8 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
               {
                 org.apache.thrift.protocol.TSet _set26 = iprot.readSetBegin();
-                struct.authorizations = new HashSet<ByteBuffer>(2*_set26.size);
-                ByteBuffer _elem27;
+                struct.authorizations = new java.util.HashSet<java.nio.ByteBuffer>(2*_set26.size);
+                java.nio.ByteBuffer _elem27;
                 for (int _i28 = 0; _i28 < _set26.size; ++_i28)
                 {
                   _elem27 = iprot.readBinary();
@@ -758,7 +725,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list29 = iprot.readListBegin();
-                struct.columns = new ArrayList<ScanColumn>(_list29.size);
+                struct.columns = new java.util.ArrayList<ScanColumn>(_list29.size);
                 ScanColumn _elem30;
                 for (int _i31 = 0; _i31 < _list29.size; ++_i31)
                 {
@@ -777,7 +744,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list32 = iprot.readListBegin();
-                struct.iterators = new ArrayList<IteratorSetting>(_list32.size);
+                struct.iterators = new java.util.ArrayList<IteratorSetting>(_list32.size);
                 IteratorSetting _elem33;
                 for (int _i34 = 0; _i34 < _list32.size; ++_i34)
                 {
@@ -820,7 +787,7 @@
           oprot.writeFieldBegin(AUTHORIZATIONS_FIELD_DESC);
           {
             oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRING, struct.authorizations.size()));
-            for (ByteBuffer _iter35 : struct.authorizations)
+            for (java.nio.ByteBuffer _iter35 : struct.authorizations)
             {
               oprot.writeBinary(_iter35);
             }
@@ -875,18 +842,18 @@
 
   }
 
-  private static class ScanOptionsTupleSchemeFactory implements SchemeFactory {
+  private static class ScanOptionsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ScanOptionsTupleScheme getScheme() {
       return new ScanOptionsTupleScheme();
     }
   }
 
-  private static class ScanOptionsTupleScheme extends TupleScheme<ScanOptions> {
+  private static class ScanOptionsTupleScheme extends org.apache.thrift.scheme.TupleScheme<ScanOptions> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, ScanOptions struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetAuthorizations()) {
         optionals.set(0);
       }
@@ -906,7 +873,7 @@
       if (struct.isSetAuthorizations()) {
         {
           oprot.writeI32(struct.authorizations.size());
-          for (ByteBuffer _iter38 : struct.authorizations)
+          for (java.nio.ByteBuffer _iter38 : struct.authorizations)
           {
             oprot.writeBinary(_iter38);
           }
@@ -940,13 +907,13 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, ScanOptions struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(5);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(5);
       if (incoming.get(0)) {
         {
           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);
-          ByteBuffer _elem42;
+          struct.authorizations = new java.util.HashSet<java.nio.ByteBuffer>(2*_set41.size);
+          java.nio.ByteBuffer _elem42;
           for (int _i43 = 0; _i43 < _set41.size; ++_i43)
           {
             _elem42 = iprot.readBinary();
@@ -963,7 +930,7 @@
       if (incoming.get(2)) {
         {
           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);
+          struct.columns = new java.util.ArrayList<ScanColumn>(_list44.size);
           ScanColumn _elem45;
           for (int _i46 = 0; _i46 < _list44.size; ++_i46)
           {
@@ -977,7 +944,7 @@
       if (incoming.get(3)) {
         {
           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);
+          struct.iterators = new java.util.ArrayList<IteratorSetting>(_list47.size);
           IteratorSetting _elem48;
           for (int _i49 = 0; _i49 < _list47.size; ++_i49)
           {
@@ -995,5 +962,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 861b0de..f5551cc 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/ScanResult.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/ScanResult.java
@@ -15,55 +15,25 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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);
   private static final org.apache.thrift.protocol.TField MORE_FIELD_DESC = new org.apache.thrift.protocol.TField("more", org.apache.thrift.protocol.TType.BOOL, (short)2);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new ScanResultStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new ScanResultTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ScanResultStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ScanResultTupleSchemeFactory();
 
-  public List<KeyValue> results; // required
+  public java.util.List<KeyValue> results; // required
   public boolean more; // required
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
@@ -71,10 +41,10 @@
     RESULTS((short)1, "results"),
     MORE((short)2, "more");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -99,21 +69,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -122,7 +92,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -130,15 +100,15 @@
   // isset id assignments
   private static final int __MORE_ISSET_ID = 0;
   private byte __isset_bitfield = 0;
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.RESULTS, new org.apache.thrift.meta_data.FieldMetaData("results", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
             new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KeyValue.class))));
     tmpMap.put(_Fields.MORE, new org.apache.thrift.meta_data.FieldMetaData("more", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ScanResult.class, metaDataMap);
   }
 
@@ -146,7 +116,7 @@
   }
 
   public ScanResult(
-    List<KeyValue> results,
+    java.util.List<KeyValue> results,
     boolean more)
   {
     this();
@@ -161,7 +131,7 @@
   public ScanResult(ScanResult other) {
     __isset_bitfield = other.__isset_bitfield;
     if (other.isSetResults()) {
-      List<KeyValue> __this__results = new ArrayList<KeyValue>(other.results.size());
+      java.util.List<KeyValue> __this__results = new java.util.ArrayList<KeyValue>(other.results.size());
       for (KeyValue other_element : other.results) {
         __this__results.add(new KeyValue(other_element));
       }
@@ -191,16 +161,16 @@
 
   public void addToResults(KeyValue elem) {
     if (this.results == null) {
-      this.results = new ArrayList<KeyValue>();
+      this.results = new java.util.ArrayList<KeyValue>();
     }
     this.results.add(elem);
   }
 
-  public List<KeyValue> getResults() {
+  public java.util.List<KeyValue> getResults() {
     return this.results;
   }
 
-  public ScanResult setResults(List<KeyValue> results) {
+  public ScanResult setResults(java.util.List<KeyValue> results) {
     this.results = results;
     return this;
   }
@@ -231,25 +201,25 @@
   }
 
   public void unsetMore() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __MORE_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __MORE_ISSET_ID);
   }
 
   /** Returns true if field more is set (has been assigned a value) and false otherwise */
   public boolean isSetMore() {
-    return EncodingUtils.testBit(__isset_bitfield, __MORE_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __MORE_ISSET_ID);
   }
 
   public void setMoreIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __MORE_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __MORE_ISSET_ID, value);
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case RESULTS:
       if (value == null) {
         unsetResults();
       } else {
-        setResults((List<KeyValue>)value);
+        setResults((java.util.List<KeyValue>)value);
       }
       break;
 
@@ -257,14 +227,14 @@
       if (value == null) {
         unsetMore();
       } else {
-        setMore((Boolean)value);
+        setMore((java.lang.Boolean)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case RESULTS:
       return getResults();
@@ -273,13 +243,13 @@
       return isMore();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -288,11 +258,11 @@
     case MORE:
       return isSetMore();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof ScanResult)
@@ -303,6 +273,8 @@
   public boolean equals(ScanResult that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_results = true && this.isSetResults();
     boolean that_present_results = true && that.isSetResults();
@@ -327,19 +299,15 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_results = true && (isSetResults());
-    list.add(present_results);
-    if (present_results)
-      list.add(results);
+    hashCode = hashCode * 8191 + ((isSetResults()) ? 131071 : 524287);
+    if (isSetResults())
+      hashCode = hashCode * 8191 + results.hashCode();
 
-    boolean present_more = true;
-    list.add(present_more);
-    if (present_more)
-      list.add(more);
+    hashCode = hashCode * 8191 + ((more) ? 131071 : 524287);
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -350,7 +318,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetResults()).compareTo(other.isSetResults());
+    lastComparison = java.lang.Boolean.valueOf(isSetResults()).compareTo(other.isSetResults());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -360,7 +328,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetMore()).compareTo(other.isSetMore());
+    lastComparison = java.lang.Boolean.valueOf(isSetMore()).compareTo(other.isSetMore());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -378,16 +346,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("ScanResult(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("ScanResult(");
     boolean first = true;
 
     sb.append("results:");
@@ -418,7 +386,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -428,13 +396,13 @@
     }
   }
 
-  private static class ScanResultStandardSchemeFactory implements SchemeFactory {
+  private static class ScanResultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ScanResultStandardScheme getScheme() {
       return new ScanResultStandardScheme();
     }
   }
 
-  private static class ScanResultStandardScheme extends StandardScheme<ScanResult> {
+  private static class ScanResultStandardScheme extends org.apache.thrift.scheme.StandardScheme<ScanResult> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, ScanResult struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -450,7 +418,7 @@
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
                 org.apache.thrift.protocol.TList _list8 = iprot.readListBegin();
-                struct.results = new ArrayList<KeyValue>(_list8.size);
+                struct.results = new java.util.ArrayList<KeyValue>(_list8.size);
                 KeyValue _elem9;
                 for (int _i10 = 0; _i10 < _list8.size; ++_i10)
                 {
@@ -509,18 +477,18 @@
 
   }
 
-  private static class ScanResultTupleSchemeFactory implements SchemeFactory {
+  private static class ScanResultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public ScanResultTupleScheme getScheme() {
       return new ScanResultTupleScheme();
     }
   }
 
-  private static class ScanResultTupleScheme extends TupleScheme<ScanResult> {
+  private static class ScanResultTupleScheme extends org.apache.thrift.scheme.TupleScheme<ScanResult> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, ScanResult struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetResults()) {
         optionals.set(0);
       }
@@ -544,12 +512,12 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, ScanResult struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(2);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(2);
       if (incoming.get(0)) {
         {
           org.apache.thrift.protocol.TList _list13 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
-          struct.results = new ArrayList<KeyValue>(_list13.size);
+          struct.results = new java.util.ArrayList<KeyValue>(_list13.size);
           KeyValue _elem14;
           for (int _i15 = 0; _i15 < _list13.size; ++_i15)
           {
@@ -567,5 +535,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 8e79212..17d390d 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum ScanState implements org.apache.thrift.TEnum {
+public enum ScanState implements org.apache.thrift.TEnum {
   IDLE(0),
   RUNNING(1),
   QUEUED(2);
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 14ac9ce..0082b71 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum ScanType implements org.apache.thrift.TEnum {
+public enum ScanType implements org.apache.thrift.TEnum {
   SINGLE(0),
   BATCH(1);
 
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 6671dec..27551a9 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum SystemPermission implements org.apache.thrift.TEnum {
+public enum SystemPermission implements org.apache.thrift.TEnum {
   GRANT(0),
   CREATE_TABLE(1),
   DROP_TABLE(2),
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 509f022..3162458 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/TableExistsException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/TableExistsException.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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 TableExistsException extends TException implements org.apache.thrift.TBase<TableExistsException, TableExistsException._Fields>, java.io.Serializable, Cloneable, Comparable<TableExistsException> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class TableExistsException extends org.apache.thrift.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);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new TableExistsExceptionStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new TableExistsExceptionTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TableExistsExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TableExistsExceptionTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TableExistsException.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public TableExistsException(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public TableExistsException setMsg(String msg) {
+  public TableExistsException setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof TableExistsException)
@@ -231,6 +201,8 @@
   public boolean equals(TableExistsException that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("TableExistsException(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("TableExistsException(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class TableExistsExceptionStandardSchemeFactory implements SchemeFactory {
+  private static class TableExistsExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public TableExistsExceptionStandardScheme getScheme() {
       return new TableExistsExceptionStandardScheme();
     }
   }
 
-  private static class TableExistsExceptionStandardScheme extends StandardScheme<TableExistsException> {
+  private static class TableExistsExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<TableExistsException> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, TableExistsException struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class TableExistsExceptionTupleSchemeFactory implements SchemeFactory {
+  private static class TableExistsExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public TableExistsExceptionTupleScheme getScheme() {
       return new TableExistsExceptionTupleScheme();
     }
   }
 
-  private static class TableExistsExceptionTupleScheme extends TupleScheme<TableExistsException> {
+  private static class TableExistsExceptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<TableExistsException> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, TableExistsException struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, TableExistsException struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(1);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 d889faf..1bc9529 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/TableNotFoundException.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/TableNotFoundException.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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 TableNotFoundException extends TException implements org.apache.thrift.TBase<TableNotFoundException, TableNotFoundException._Fields>, java.io.Serializable, Cloneable, Comparable<TableNotFoundException> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class TableNotFoundException extends org.apache.thrift.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);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new TableNotFoundExceptionStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new TableNotFoundExceptionTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TableNotFoundExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TableNotFoundExceptionTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TableNotFoundException.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public TableNotFoundException(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public TableNotFoundException setMsg(String msg) {
+  public TableNotFoundException setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof TableNotFoundException)
@@ -231,6 +201,8 @@
   public boolean equals(TableNotFoundException that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("TableNotFoundException(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("TableNotFoundException(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class TableNotFoundExceptionStandardSchemeFactory implements SchemeFactory {
+  private static class TableNotFoundExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public TableNotFoundExceptionStandardScheme getScheme() {
       return new TableNotFoundExceptionStandardScheme();
     }
   }
 
-  private static class TableNotFoundExceptionStandardScheme extends StandardScheme<TableNotFoundException> {
+  private static class TableNotFoundExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<TableNotFoundException> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, TableNotFoundException struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class TableNotFoundExceptionTupleSchemeFactory implements SchemeFactory {
+  private static class TableNotFoundExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public TableNotFoundExceptionTupleScheme getScheme() {
       return new TableNotFoundExceptionTupleScheme();
     }
   }
 
-  private static class TableNotFoundExceptionTupleScheme extends TupleScheme<TableNotFoundException> {
+  private static class TableNotFoundExceptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<TableNotFoundException> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, TableNotFoundException struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, TableNotFoundException struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(1);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 1beac63..c969452 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum TablePermission implements org.apache.thrift.TEnum {
+public enum TablePermission implements org.apache.thrift.TEnum {
   READ(2),
   WRITE(3),
   BULK_IMPORT(4),
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 26565a2..26ebb62 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.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
  *  @generated
@@ -23,11 +23,8 @@
 package org.apache.accumulo.proxy.thrift;
 
 
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
 
-@SuppressWarnings({"unused"}) public enum TimeType implements org.apache.thrift.TEnum {
+public enum TimeType implements org.apache.thrift.TEnum {
   LOGICAL(0),
   MILLIS(1);
 
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 3630f94..82ea224 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/UnknownScanner.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/UnknownScanner.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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 UnknownScanner extends TException implements org.apache.thrift.TBase<UnknownScanner, UnknownScanner._Fields>, java.io.Serializable, Cloneable, Comparable<UnknownScanner> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class UnknownScanner extends org.apache.thrift.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);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new UnknownScannerStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new UnknownScannerTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new UnknownScannerStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new UnknownScannerTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(UnknownScanner.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public UnknownScanner(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public UnknownScanner setMsg(String msg) {
+  public UnknownScanner setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof UnknownScanner)
@@ -231,6 +201,8 @@
   public boolean equals(UnknownScanner that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("UnknownScanner(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("UnknownScanner(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class UnknownScannerStandardSchemeFactory implements SchemeFactory {
+  private static class UnknownScannerStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public UnknownScannerStandardScheme getScheme() {
       return new UnknownScannerStandardScheme();
     }
   }
 
-  private static class UnknownScannerStandardScheme extends StandardScheme<UnknownScanner> {
+  private static class UnknownScannerStandardScheme extends org.apache.thrift.scheme.StandardScheme<UnknownScanner> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, UnknownScanner struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class UnknownScannerTupleSchemeFactory implements SchemeFactory {
+  private static class UnknownScannerTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public UnknownScannerTupleScheme getScheme() {
       return new UnknownScannerTupleScheme();
     }
   }
 
-  private static class UnknownScannerTupleScheme extends TupleScheme<UnknownScanner> {
+  private static class UnknownScannerTupleScheme extends org.apache.thrift.scheme.TupleScheme<UnknownScanner> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, UnknownScanner struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, UnknownScanner struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(1);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 cd82742..8a7969c 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/UnknownWriter.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/UnknownWriter.java
@@ -15,63 +15,33 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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 UnknownWriter extends TException implements org.apache.thrift.TBase<UnknownWriter, UnknownWriter._Fields>, java.io.Serializable, Cloneable, Comparable<UnknownWriter> {
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
+public class UnknownWriter extends org.apache.thrift.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);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new UnknownWriterStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new UnknownWriterTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new UnknownWriterStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new UnknownWriterTupleSchemeFactory();
 
-  public String msg; // required
+  public java.lang.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>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -94,21 +64,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -117,18 +87,18 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
 
   // isset id assignments
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(UnknownWriter.class, metaDataMap);
   }
 
@@ -136,7 +106,7 @@
   }
 
   public UnknownWriter(
-    String msg)
+    java.lang.String msg)
   {
     this();
     this.msg = msg;
@@ -160,11 +130,11 @@
     this.msg = null;
   }
 
-  public String getMsg() {
+  public java.lang.String getMsg() {
     return this.msg;
   }
 
-  public UnknownWriter setMsg(String msg) {
+  public UnknownWriter setMsg(java.lang.String msg) {
     this.msg = msg;
     return this;
   }
@@ -184,43 +154,43 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((java.lang.String)value);
       }
       break;
 
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MSG:
       return getMsg();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
     case MSG:
       return isSetMsg();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof UnknownWriter)
@@ -231,6 +201,8 @@
   public boolean equals(UnknownWriter that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
@@ -246,14 +218,13 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_msg = true && (isSetMsg());
-    list.add(present_msg);
-    if (present_msg)
-      list.add(msg);
+    hashCode = hashCode * 8191 + ((isSetMsg()) ? 131071 : 524287);
+    if (isSetMsg())
+      hashCode = hashCode * 8191 + msg.hashCode();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -264,7 +235,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
+    lastComparison = java.lang.Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -282,16 +253,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("UnknownWriter(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("UnknownWriter(");
     boolean first = true;
 
     sb.append("msg:");
@@ -318,7 +289,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
     try {
       read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
     } catch (org.apache.thrift.TException te) {
@@ -326,13 +297,13 @@
     }
   }
 
-  private static class UnknownWriterStandardSchemeFactory implements SchemeFactory {
+  private static class UnknownWriterStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public UnknownWriterStandardScheme getScheme() {
       return new UnknownWriterStandardScheme();
     }
   }
 
-  private static class UnknownWriterStandardScheme extends StandardScheme<UnknownWriter> {
+  private static class UnknownWriterStandardScheme extends org.apache.thrift.scheme.StandardScheme<UnknownWriter> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, UnknownWriter struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -378,18 +349,18 @@
 
   }
 
-  private static class UnknownWriterTupleSchemeFactory implements SchemeFactory {
+  private static class UnknownWriterTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public UnknownWriterTupleScheme getScheme() {
       return new UnknownWriterTupleScheme();
     }
   }
 
-  private static class UnknownWriterTupleScheme extends TupleScheme<UnknownWriter> {
+  private static class UnknownWriterTupleScheme extends org.apache.thrift.scheme.TupleScheme<UnknownWriter> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, UnknownWriter struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMsg()) {
         optionals.set(0);
       }
@@ -401,8 +372,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, UnknownWriter struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(1);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         struct.msg = iprot.readString();
         struct.setMsgIsSet(true);
@@ -410,5 +381,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
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 02d4548..25b48a8 100644
--- a/src/main/java/org/apache/accumulo/proxy/thrift/WriterOptions.java
+++ b/src/main/java/org/apache/accumulo/proxy/thrift/WriterOptions.java
@@ -15,42 +15,15 @@
  * limitations under the License.
  */
 /**
- * Autogenerated by Thrift Compiler (0.9.3)
+ * Autogenerated by Thrift Compiler (0.10.0)
  *
  * 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)")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
 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");
 
@@ -60,11 +33,8 @@
   private static final org.apache.thrift.protocol.TField THREADS_FIELD_DESC = new org.apache.thrift.protocol.TField("threads", org.apache.thrift.protocol.TType.I32, (short)4);
   private static final org.apache.thrift.protocol.TField DURABILITY_FIELD_DESC = new org.apache.thrift.protocol.TField("durability", org.apache.thrift.protocol.TType.I32, (short)5);
 
-  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
-  static {
-    schemes.put(StandardScheme.class, new WriterOptionsStandardSchemeFactory());
-    schemes.put(TupleScheme.class, new WriterOptionsTupleSchemeFactory());
-  }
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new WriterOptionsStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new WriterOptionsTupleSchemeFactory();
 
   public long maxMemory; // required
   public long latencyMs; // required
@@ -88,10 +58,10 @@
      */
     DURABILITY((short)5, "durability");
 
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
     static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
         byName.put(field.getFieldName(), field);
       }
     }
@@ -122,21 +92,21 @@
      */
     public static _Fields findByThriftIdOrThrow(int fieldId) {
       _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      if (fields == null) throw new java.lang.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) {
+    public static _Fields findByName(java.lang.String name) {
       return byName.get(name);
     }
 
     private final short _thriftId;
-    private final String _fieldName;
+    private final java.lang.String _fieldName;
 
-    _Fields(short thriftId, String fieldName) {
+    _Fields(short thriftId, java.lang.String fieldName) {
       _thriftId = thriftId;
       _fieldName = fieldName;
     }
@@ -145,7 +115,7 @@
       return _thriftId;
     }
 
-    public String getFieldName() {
+    public java.lang.String getFieldName() {
       return _fieldName;
     }
   }
@@ -157,9 +127,9 @@
   private static final int __THREADS_ISSET_ID = 3;
   private byte __isset_bitfield = 0;
   private static final _Fields optionals[] = {_Fields.DURABILITY};
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  public static final java.util.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);
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.MAX_MEMORY, new org.apache.thrift.meta_data.FieldMetaData("maxMemory", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
     tmpMap.put(_Fields.LATENCY_MS, new org.apache.thrift.meta_data.FieldMetaData("latencyMs", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -170,7 +140,7 @@
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
     tmpMap.put(_Fields.DURABILITY, new org.apache.thrift.meta_data.FieldMetaData("durability", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, Durability.class)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(WriterOptions.class, metaDataMap);
   }
 
@@ -236,16 +206,16 @@
   }
 
   public void unsetMaxMemory() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __MAXMEMORY_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __MAXMEMORY_ISSET_ID);
   }
 
   /** Returns true if field maxMemory is set (has been assigned a value) and false otherwise */
   public boolean isSetMaxMemory() {
-    return EncodingUtils.testBit(__isset_bitfield, __MAXMEMORY_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __MAXMEMORY_ISSET_ID);
   }
 
   public void setMaxMemoryIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __MAXMEMORY_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __MAXMEMORY_ISSET_ID, value);
   }
 
   public long getLatencyMs() {
@@ -259,16 +229,16 @@
   }
 
   public void unsetLatencyMs() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LATENCYMS_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __LATENCYMS_ISSET_ID);
   }
 
   /** Returns true if field latencyMs is set (has been assigned a value) and false otherwise */
   public boolean isSetLatencyMs() {
-    return EncodingUtils.testBit(__isset_bitfield, __LATENCYMS_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __LATENCYMS_ISSET_ID);
   }
 
   public void setLatencyMsIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LATENCYMS_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LATENCYMS_ISSET_ID, value);
   }
 
   public long getTimeoutMs() {
@@ -282,16 +252,16 @@
   }
 
   public void unsetTimeoutMs() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID);
   }
 
   /** Returns true if field timeoutMs is set (has been assigned a value) and false otherwise */
   public boolean isSetTimeoutMs() {
-    return EncodingUtils.testBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID);
   }
 
   public void setTimeoutMsIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID, value);
   }
 
   public int getThreads() {
@@ -305,16 +275,16 @@
   }
 
   public void unsetThreads() {
-    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __THREADS_ISSET_ID);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __THREADS_ISSET_ID);
   }
 
   /** Returns true if field threads is set (has been assigned a value) and false otherwise */
   public boolean isSetThreads() {
-    return EncodingUtils.testBit(__isset_bitfield, __THREADS_ISSET_ID);
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __THREADS_ISSET_ID);
   }
 
   public void setThreadsIsSet(boolean value) {
-    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __THREADS_ISSET_ID, value);
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __THREADS_ISSET_ID, value);
   }
 
   /**
@@ -349,13 +319,13 @@
     }
   }
 
-  public void setFieldValue(_Fields field, Object value) {
+  public void setFieldValue(_Fields field, java.lang.Object value) {
     switch (field) {
     case MAX_MEMORY:
       if (value == null) {
         unsetMaxMemory();
       } else {
-        setMaxMemory((Long)value);
+        setMaxMemory((java.lang.Long)value);
       }
       break;
 
@@ -363,7 +333,7 @@
       if (value == null) {
         unsetLatencyMs();
       } else {
-        setLatencyMs((Long)value);
+        setLatencyMs((java.lang.Long)value);
       }
       break;
 
@@ -371,7 +341,7 @@
       if (value == null) {
         unsetTimeoutMs();
       } else {
-        setTimeoutMs((Long)value);
+        setTimeoutMs((java.lang.Long)value);
       }
       break;
 
@@ -379,7 +349,7 @@
       if (value == null) {
         unsetThreads();
       } else {
-        setThreads((Integer)value);
+        setThreads((java.lang.Integer)value);
       }
       break;
 
@@ -394,7 +364,7 @@
     }
   }
 
-  public Object getFieldValue(_Fields field) {
+  public java.lang.Object getFieldValue(_Fields field) {
     switch (field) {
     case MAX_MEMORY:
       return getMaxMemory();
@@ -412,13 +382,13 @@
       return getDurability();
 
     }
-    throw new IllegalStateException();
+    throw new java.lang.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();
+      throw new java.lang.IllegalArgumentException();
     }
 
     switch (field) {
@@ -433,11 +403,11 @@
     case DURABILITY:
       return isSetDurability();
     }
-    throw new IllegalStateException();
+    throw new java.lang.IllegalStateException();
   }
 
   @Override
-  public boolean equals(Object that) {
+  public boolean equals(java.lang.Object that) {
     if (that == null)
       return false;
     if (that instanceof WriterOptions)
@@ -448,6 +418,8 @@
   public boolean equals(WriterOptions that) {
     if (that == null)
       return false;
+    if (this == that)
+      return true;
 
     boolean this_present_maxMemory = true;
     boolean that_present_maxMemory = true;
@@ -499,34 +471,21 @@
 
   @Override
   public int hashCode() {
-    List<Object> list = new ArrayList<Object>();
+    int hashCode = 1;
 
-    boolean present_maxMemory = true;
-    list.add(present_maxMemory);
-    if (present_maxMemory)
-      list.add(maxMemory);
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(maxMemory);
 
-    boolean present_latencyMs = true;
-    list.add(present_latencyMs);
-    if (present_latencyMs)
-      list.add(latencyMs);
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(latencyMs);
 
-    boolean present_timeoutMs = true;
-    list.add(present_timeoutMs);
-    if (present_timeoutMs)
-      list.add(timeoutMs);
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(timeoutMs);
 
-    boolean present_threads = true;
-    list.add(present_threads);
-    if (present_threads)
-      list.add(threads);
+    hashCode = hashCode * 8191 + threads;
 
-    boolean present_durability = true && (isSetDurability());
-    list.add(present_durability);
-    if (present_durability)
-      list.add(durability.getValue());
+    hashCode = hashCode * 8191 + ((isSetDurability()) ? 131071 : 524287);
+    if (isSetDurability())
+      hashCode = hashCode * 8191 + durability.getValue();
 
-    return list.hashCode();
+    return hashCode;
   }
 
   @Override
@@ -537,7 +496,7 @@
 
     int lastComparison = 0;
 
-    lastComparison = Boolean.valueOf(isSetMaxMemory()).compareTo(other.isSetMaxMemory());
+    lastComparison = java.lang.Boolean.valueOf(isSetMaxMemory()).compareTo(other.isSetMaxMemory());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -547,7 +506,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetLatencyMs()).compareTo(other.isSetLatencyMs());
+    lastComparison = java.lang.Boolean.valueOf(isSetLatencyMs()).compareTo(other.isSetLatencyMs());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -557,7 +516,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetTimeoutMs()).compareTo(other.isSetTimeoutMs());
+    lastComparison = java.lang.Boolean.valueOf(isSetTimeoutMs()).compareTo(other.isSetTimeoutMs());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -567,7 +526,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetThreads()).compareTo(other.isSetThreads());
+    lastComparison = java.lang.Boolean.valueOf(isSetThreads()).compareTo(other.isSetThreads());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -577,7 +536,7 @@
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetDurability()).compareTo(other.isSetDurability());
+    lastComparison = java.lang.Boolean.valueOf(isSetDurability()).compareTo(other.isSetDurability());
     if (lastComparison != 0) {
       return lastComparison;
     }
@@ -595,16 +554,16 @@
   }
 
   public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    scheme(iprot).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);
+    scheme(oprot).write(oprot, this);
   }
 
   @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("WriterOptions(");
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("WriterOptions(");
     boolean first = true;
 
     sb.append("maxMemory:");
@@ -649,7 +608,7 @@
     }
   }
 
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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;
@@ -659,13 +618,13 @@
     }
   }
 
-  private static class WriterOptionsStandardSchemeFactory implements SchemeFactory {
+  private static class WriterOptionsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public WriterOptionsStandardScheme getScheme() {
       return new WriterOptionsStandardScheme();
     }
   }
 
-  private static class WriterOptionsStandardScheme extends StandardScheme<WriterOptions> {
+  private static class WriterOptionsStandardScheme extends org.apache.thrift.scheme.StandardScheme<WriterOptions> {
 
     public void read(org.apache.thrift.protocol.TProtocol iprot, WriterOptions struct) throws org.apache.thrift.TException {
       org.apache.thrift.protocol.TField schemeField;
@@ -757,18 +716,18 @@
 
   }
 
-  private static class WriterOptionsTupleSchemeFactory implements SchemeFactory {
+  private static class WriterOptionsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
     public WriterOptionsTupleScheme getScheme() {
       return new WriterOptionsTupleScheme();
     }
   }
 
-  private static class WriterOptionsTupleScheme extends TupleScheme<WriterOptions> {
+  private static class WriterOptionsTupleScheme extends org.apache.thrift.scheme.TupleScheme<WriterOptions> {
 
     @Override
     public void write(org.apache.thrift.protocol.TProtocol prot, WriterOptions struct) throws org.apache.thrift.TException {
-      TTupleProtocol oprot = (TTupleProtocol) prot;
-      BitSet optionals = new BitSet();
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
       if (struct.isSetMaxMemory()) {
         optionals.set(0);
       }
@@ -804,8 +763,8 @@
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, WriterOptions struct) throws org.apache.thrift.TException {
-      TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(5);
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(5);
       if (incoming.get(0)) {
         struct.maxMemory = iprot.readI64();
         struct.setMaxMemoryIsSet(true);
@@ -829,5 +788,9 @@
     }
   }
 
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+  private static void unusedMethod() {}
 }
 
diff --git a/src/main/python/AccumuloProxy-remote b/src/main/python/AccumuloProxy-remote
index bc08e9b..a98dd67 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.3)
+# Autogenerated by Thrift Compiler (0.10.0)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
@@ -23,779 +23,802 @@
 
 import sys
 import pprint
-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
+if sys.version_info[0] > 2:
+    from urllib.parse import urlparse
+else:
+    from urlparse import urlparse
+from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient
+from thrift.protocol.TBinaryProtocol import TBinaryProtocol
 
 from accumulo import AccumuloProxy
 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]] [-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)
+    print('')
+    print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] 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)
+pp = pprint.PrettyPrinter(indent=2)
 host = 'localhost'
 port = 9090
 uri = ''
 framed = False
 ssl = False
+validate = True
+ca_certs = None
+keyfile = None
+certfile = None
 http = False
 argi = 1
 
 if sys.argv[argi] == '-h':
-  parts = sys.argv[argi+1].split(':')
-  host = parts[0]
-  if len(parts) > 1:
-    port = int(parts[1])
-  argi += 2
+    parts = sys.argv[argi + 1].split(':')
+    host = parts[0]
+    if len(parts) > 1:
+        port = int(parts[1])
+    argi += 2
 
 if sys.argv[argi] == '-u':
-  url = urlparse(sys.argv[argi+1])
-  parts = url[1].split(':')
-  host = parts[0]
-  if len(parts) > 1:
-    port = int(parts[1])
-  else:
-    port = 80
-  uri = url[2]
-  if url[4]:
-    uri += '?%s' % url[4]
-  http = True
-  argi += 2
+    url = urlparse(sys.argv[argi + 1])
+    parts = url[1].split(':')
+    host = parts[0]
+    if len(parts) > 1:
+        port = int(parts[1])
+    else:
+        port = 80
+    uri = url[2]
+    if url[4]:
+        uri += '?%s' % url[4]
+    http = True
+    argi += 2
 
 if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':
-  framed = True
-  argi += 1
+    framed = True
+    argi += 1
 
 if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':
-  ssl = True
-  argi += 1
+    ssl = True
+    argi += 1
+
+if sys.argv[argi] == '-novalidate':
+    validate = False
+    argi += 1
+
+if sys.argv[argi] == '-ca_certs':
+    ca_certs = sys.argv[argi+1]
+    argi += 2
+
+if sys.argv[argi] == '-keyfile':
+    keyfile = sys.argv[argi+1]
+    argi += 2
+
+if sys.argv[argi] == '-certfile':
+    certfile = sys.argv[argi+1]
+    argi += 2
 
 cmd = sys.argv[argi]
-args = sys.argv[argi+1:]
+args = sys.argv[argi + 1:]
 
 if http:
-  transport = THttpClient.THttpClient(host, port, uri)
+    transport = THttpClient.THttpClient(host, port, uri)
 else:
-  socket = TSSLSocket.TSSLSocket(host, port, validate=False) if ssl else TSocket.TSocket(host, port)
-  if framed:
-    transport = TTransport.TFramedTransport(socket)
-  else:
-    transport = TTransport.TBufferedTransport(socket)
-protocol = TBinaryProtocol.TBinaryProtocol(transport)
+    if ssl:
+        socket = TSSLSocket.TSSLSocket(host, port, validate=validate, ca_certs=ca_certs, keyfile=keyfile, certfile=certfile)
+    else:
+        socket = TSocket.TSocket(host, port)
+    if framed:
+        transport = TTransport.TFramedTransport(socket)
+    else:
+        transport = TTransport.TBufferedTransport(socket)
+protocol = TBinaryProtocol(transport)
 client = AccumuloProxy.Client(protocol)
 transport.open()
 
 if cmd == 'login':
-  if len(args) != 2:
-    print('login requires 2 args')
-    sys.exit(1)
-  pp.pprint(client.login(args[0],eval(args[1]),))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.addConstraint(args[0],args[1],args[2],))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.addSplits(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.attachIterator(args[0],args[1],eval(args[2]),eval(args[3]),))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.checkIteratorConflicts(args[0],args[1],eval(args[2]),eval(args[3]),))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.clearLocatorCache(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.cloneTable(args[0],args[1],args[2],eval(args[3]),eval(args[4]),eval(args[5]),))
+    if len(args) != 6:
+        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')
-    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]),))
+    if len(args) != 8:
+        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')
-    sys.exit(1)
-  pp.pprint(client.cancelCompaction(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.createTable(args[0],args[1],eval(args[2]),eval(args[3]),))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.deleteTable(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.deleteRows(args[0],args[1],args[2],args[3],))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.exportTable(args[0],args[1],args[2],))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.flushTable(args[0],args[1],args[2],args[3],eval(args[4]),))
+    if len(args) != 5:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getDiskUsage(args[0],eval(args[1]),))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getLocalityGroups(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getIteratorSetting(args[0],args[1],args[2],eval(args[3]),))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getMaxRow(args[0],args[1],eval(args[2]),args[3],eval(args[4]),args[5],eval(args[6]),))
+    if len(args) != 7:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getTableProperties(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.importDirectory(args[0],args[1],args[2],args[3],eval(args[4]),))
+    if len(args) != 5:
+        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')
-    sys.exit(1)
-  pp.pprint(client.importTable(args[0],args[1],args[2],))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.listSplits(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.listTables(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.listIterators(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.listConstraints(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.mergeTablets(args[0],args[1],args[2],args[3],))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.offlineTable(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.onlineTable(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.removeConstraint(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.removeIterator(args[0],args[1],args[2],eval(args[3]),))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.removeTableProperty(args[0],args[1],args[2],))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.renameTable(args[0],args[1],args[2],))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.setLocalityGroups(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.setTableProperty(args[0],args[1],args[2],args[3],))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.splitRangeByTablets(args[0],args[1],eval(args[2]),eval(args[3]),))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.tableExists(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.tableIdMap(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.testTableClassLoad(args[0],args[1],args[2],args[3],))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.pingTabletServer(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getActiveScans(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getActiveCompactions(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getSiteConfiguration(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getSystemConfiguration(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getTabletServers(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.removeProperty(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.setProperty(args[0],args[1],args[2],))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.testClassLoad(args[0],args[1],args[2],))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.authenticateUser(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.changeUserAuthorizations(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.changeLocalUserPassword(args[0],args[1],args[2],))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.createLocalUser(args[0],args[1],args[2],))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.dropLocalUser(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getUserAuthorizations(args[0],args[1],))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.grantSystemPermission(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.grantTablePermission(args[0],args[1],args[2],eval(args[3]),))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.hasSystemPermission(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.hasTablePermission(args[0],args[1],args[2],eval(args[3]),))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.listLocalUsers(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.revokeSystemPermission(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.revokeTablePermission(args[0],args[1],args[2],eval(args[3]),))
+    if len(args) != 4:
+        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]),))
+    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]),))
+    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]),))
+    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')
-    sys.exit(1)
-  pp.pprint(client.createBatchScanner(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.createScanner(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.hasNext(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.nextEntry(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.nextK(args[0],eval(args[1]),))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.closeScanner(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.updateAndFlush(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.createWriter(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.update(args[0],eval(args[1]),))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.flush(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.closeWriter(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.updateRowConditionally(args[0],args[1],args[2],eval(args[3]),))
+    if len(args) != 4:
+        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')
-    sys.exit(1)
-  pp.pprint(client.createConditionalWriter(args[0],args[1],eval(args[2]),))
+    if len(args) != 3:
+        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')
-    sys.exit(1)
-  pp.pprint(client.updateRowsConditionally(args[0],eval(args[1]),))
+    if len(args) != 2:
+        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')
-    sys.exit(1)
-  pp.pprint(client.closeConditionalWriter(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getRowRange(args[0],))
+    if len(args) != 1:
+        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')
-    sys.exit(1)
-  pp.pprint(client.getFollowing(eval(args[0]),eval(args[1]),))
+    if len(args) != 2:
+        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())
+    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())
+    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],))
+    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],))
+    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],))
+    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],))
+    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],))
+    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],))
+    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],))
+    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],))
+    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],))
+    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]),))
+    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]),))
+    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]),))
+    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],))
+    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]),))
+    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],))
+    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]),))
+    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],))
+    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],))
+    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)
-  sys.exit(1)
+    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 19bd257..ea6e63a 100644
--- a/src/main/python/AccumuloProxy.py
+++ b/src/main/python/AccumuloProxy.py
@@ -13,1138 +13,8495 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Autogenerated by Thrift Compiler (0.9.3)
+# Autogenerated by Thrift Compiler (0.10.0)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
 #  options string: py
 #
 
-from thrift.Thrift import TType, TMessageType, TException, TApplicationException
+from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException
+from thrift.protocol.TProtocol import TProtocolException
+import sys
 import logging
-from ttypes import *
+from .ttypes import *
 from thrift.Thrift import TProcessor
 from thrift.transport import TTransport
-from thrift.protocol import TBinaryProtocol, TProtocol
-try:
-  from thrift.protocol import fastbinary
-except:
-  fastbinary = None
 
 
-class Iface:
-  def login(self, principal, loginProperties):
-    """
-    Parameters:
-     - principal
-     - loginProperties
-    """
-    pass
+class Iface(object):
+    def login(self, principal, loginProperties):
+        """
+        Parameters:
+         - principal
+         - loginProperties
+        """
+        pass
 
-  def addConstraint(self, login, tableName, constraintClassName):
-    """
-    Parameters:
-     - login
-     - tableName
-     - constraintClassName
-    """
-    pass
+    def addConstraint(self, login, tableName, constraintClassName):
+        """
+        Parameters:
+         - login
+         - tableName
+         - constraintClassName
+        """
+        pass
 
-  def addSplits(self, login, tableName, splits):
-    """
-    Parameters:
-     - login
-     - tableName
-     - splits
-    """
-    pass
+    def addSplits(self, login, tableName, splits):
+        """
+        Parameters:
+         - login
+         - tableName
+         - splits
+        """
+        pass
 
-  def attachIterator(self, login, tableName, setting, scopes):
-    """
-    Parameters:
-     - login
-     - tableName
-     - setting
-     - scopes
-    """
-    pass
+    def attachIterator(self, login, tableName, setting, scopes):
+        """
+        Parameters:
+         - login
+         - tableName
+         - setting
+         - scopes
+        """
+        pass
 
-  def checkIteratorConflicts(self, login, tableName, setting, scopes):
-    """
-    Parameters:
-     - login
-     - tableName
-     - setting
-     - scopes
-    """
-    pass
+    def checkIteratorConflicts(self, login, tableName, setting, scopes):
+        """
+        Parameters:
+         - login
+         - tableName
+         - setting
+         - scopes
+        """
+        pass
 
-  def clearLocatorCache(self, login, tableName):
-    """
-    Parameters:
-     - login
-     - tableName
-    """
-    pass
+    def clearLocatorCache(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        pass
 
-  def cloneTable(self, login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude):
-    """
-    Parameters:
-     - login
-     - tableName
-     - newTableName
-     - flush
-     - propertiesToSet
-     - propertiesToExclude
-    """
-    pass
+    def cloneTable(self, login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude):
+        """
+        Parameters:
+         - login
+         - tableName
+         - newTableName
+         - flush
+         - propertiesToSet
+         - propertiesToExclude
+        """
+        pass
 
-  def compactTable(self, login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy):
-    """
-    Parameters:
-     - login
-     - tableName
-     - startRow
-     - endRow
-     - iterators
-     - flush
-     - wait
-     - compactionStrategy
-    """
-    pass
+    def compactTable(self, login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy):
+        """
+        Parameters:
+         - login
+         - tableName
+         - startRow
+         - endRow
+         - iterators
+         - flush
+         - wait
+         - compactionStrategy
+        """
+        pass
 
-  def cancelCompaction(self, login, tableName):
-    """
-    Parameters:
-     - login
-     - tableName
-    """
-    pass
+    def cancelCompaction(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        pass
 
-  def createTable(self, login, tableName, versioningIter, type):
-    """
-    Parameters:
-     - login
-     - tableName
-     - versioningIter
-     - type
-    """
-    pass
+    def createTable(self, login, tableName, versioningIter, type):
+        """
+        Parameters:
+         - login
+         - tableName
+         - versioningIter
+         - type
+        """
+        pass
 
-  def deleteTable(self, login, tableName):
-    """
-    Parameters:
-     - login
-     - tableName
-    """
-    pass
+    def deleteTable(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        pass
 
-  def deleteRows(self, login, tableName, startRow, endRow):
-    """
-    Parameters:
-     - login
-     - tableName
-     - startRow
-     - endRow
-    """
-    pass
+    def deleteRows(self, login, tableName, startRow, endRow):
+        """
+        Parameters:
+         - login
+         - tableName
+         - startRow
+         - endRow
+        """
+        pass
 
-  def exportTable(self, login, tableName, exportDir):
-    """
-    Parameters:
-     - login
-     - tableName
-     - exportDir
-    """
-    pass
+    def exportTable(self, login, tableName, exportDir):
+        """
+        Parameters:
+         - login
+         - tableName
+         - exportDir
+        """
+        pass
 
-  def flushTable(self, login, tableName, startRow, endRow, wait):
-    """
-    Parameters:
-     - login
-     - tableName
-     - startRow
-     - endRow
-     - wait
-    """
-    pass
+    def flushTable(self, login, tableName, startRow, endRow, wait):
+        """
+        Parameters:
+         - login
+         - tableName
+         - startRow
+         - endRow
+         - wait
+        """
+        pass
 
-  def getDiskUsage(self, login, tables):
-    """
-    Parameters:
-     - login
-     - tables
-    """
-    pass
+    def getDiskUsage(self, login, tables):
+        """
+        Parameters:
+         - login
+         - tables
+        """
+        pass
 
-  def getLocalityGroups(self, login, tableName):
-    """
-    Parameters:
-     - login
-     - tableName
-    """
-    pass
+    def getLocalityGroups(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        pass
 
-  def getIteratorSetting(self, login, tableName, iteratorName, scope):
-    """
-    Parameters:
-     - login
-     - tableName
-     - iteratorName
-     - scope
-    """
-    pass
+    def getIteratorSetting(self, login, tableName, iteratorName, scope):
+        """
+        Parameters:
+         - login
+         - tableName
+         - iteratorName
+         - scope
+        """
+        pass
 
-  def getMaxRow(self, login, tableName, auths, startRow, startInclusive, endRow, endInclusive):
-    """
-    Parameters:
-     - login
-     - tableName
-     - auths
-     - startRow
-     - startInclusive
-     - endRow
-     - endInclusive
-    """
-    pass
+    def getMaxRow(self, login, tableName, auths, startRow, startInclusive, endRow, endInclusive):
+        """
+        Parameters:
+         - login
+         - tableName
+         - auths
+         - startRow
+         - startInclusive
+         - endRow
+         - endInclusive
+        """
+        pass
 
-  def getTableProperties(self, login, tableName):
-    """
-    Parameters:
-     - login
-     - tableName
-    """
-    pass
+    def getTableProperties(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        pass
 
-  def importDirectory(self, login, tableName, importDir, failureDir, setTime):
-    """
-    Parameters:
-     - login
-     - tableName
-     - importDir
-     - failureDir
-     - setTime
-    """
-    pass
+    def importDirectory(self, login, tableName, importDir, failureDir, setTime):
+        """
+        Parameters:
+         - login
+         - tableName
+         - importDir
+         - failureDir
+         - setTime
+        """
+        pass
 
-  def importTable(self, login, tableName, importDir):
-    """
-    Parameters:
-     - login
-     - tableName
-     - importDir
-    """
-    pass
+    def importTable(self, login, tableName, importDir):
+        """
+        Parameters:
+         - login
+         - tableName
+         - importDir
+        """
+        pass
 
-  def listSplits(self, login, tableName, maxSplits):
-    """
-    Parameters:
-     - login
-     - tableName
-     - maxSplits
-    """
-    pass
+    def listSplits(self, login, tableName, maxSplits):
+        """
+        Parameters:
+         - login
+         - tableName
+         - maxSplits
+        """
+        pass
 
-  def listTables(self, login):
-    """
-    Parameters:
-     - login
-    """
-    pass
+    def listTables(self, login):
+        """
+        Parameters:
+         - login
+        """
+        pass
 
-  def listIterators(self, login, tableName):
-    """
-    Parameters:
-     - login
-     - tableName
-    """
-    pass
+    def listIterators(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        pass
 
-  def listConstraints(self, login, tableName):
-    """
-    Parameters:
-     - login
-     - tableName
-    """
-    pass
+    def listConstraints(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        pass
 
-  def mergeTablets(self, login, tableName, startRow, endRow):
-    """
-    Parameters:
-     - login
-     - tableName
-     - startRow
-     - endRow
-    """
-    pass
+    def mergeTablets(self, login, tableName, startRow, endRow):
+        """
+        Parameters:
+         - login
+         - tableName
+         - startRow
+         - endRow
+        """
+        pass
 
-  def offlineTable(self, login, tableName, wait):
-    """
-    Parameters:
-     - login
-     - tableName
-     - wait
-    """
-    pass
+    def offlineTable(self, login, tableName, wait):
+        """
+        Parameters:
+         - login
+         - tableName
+         - wait
+        """
+        pass
 
-  def onlineTable(self, login, tableName, wait):
-    """
-    Parameters:
-     - login
-     - tableName
-     - wait
-    """
-    pass
+    def onlineTable(self, login, tableName, wait):
+        """
+        Parameters:
+         - login
+         - tableName
+         - wait
+        """
+        pass
 
-  def removeConstraint(self, login, tableName, constraint):
-    """
-    Parameters:
-     - login
-     - tableName
-     - constraint
-    """
-    pass
+    def removeConstraint(self, login, tableName, constraint):
+        """
+        Parameters:
+         - login
+         - tableName
+         - constraint
+        """
+        pass
 
-  def removeIterator(self, login, tableName, iterName, scopes):
-    """
-    Parameters:
-     - login
-     - tableName
-     - iterName
-     - scopes
-    """
-    pass
+    def removeIterator(self, login, tableName, iterName, scopes):
+        """
+        Parameters:
+         - login
+         - tableName
+         - iterName
+         - scopes
+        """
+        pass
 
-  def removeTableProperty(self, login, tableName, property):
-    """
-    Parameters:
-     - login
-     - tableName
-     - property
-    """
-    pass
+    def removeTableProperty(self, login, tableName, property):
+        """
+        Parameters:
+         - login
+         - tableName
+         - property
+        """
+        pass
 
-  def renameTable(self, login, oldTableName, newTableName):
-    """
-    Parameters:
-     - login
-     - oldTableName
-     - newTableName
-    """
-    pass
+    def renameTable(self, login, oldTableName, newTableName):
+        """
+        Parameters:
+         - login
+         - oldTableName
+         - newTableName
+        """
+        pass
 
-  def setLocalityGroups(self, login, tableName, groups):
-    """
-    Parameters:
-     - login
-     - tableName
-     - groups
-    """
-    pass
+    def setLocalityGroups(self, login, tableName, groups):
+        """
+        Parameters:
+         - login
+         - tableName
+         - groups
+        """
+        pass
 
-  def setTableProperty(self, login, tableName, property, value):
-    """
-    Parameters:
-     - login
-     - tableName
-     - property
-     - value
-    """
-    pass
+    def setTableProperty(self, login, tableName, property, value):
+        """
+        Parameters:
+         - login
+         - tableName
+         - property
+         - value
+        """
+        pass
 
-  def splitRangeByTablets(self, login, tableName, range, maxSplits):
-    """
-    Parameters:
-     - login
-     - tableName
-     - range
-     - maxSplits
-    """
-    pass
+    def splitRangeByTablets(self, login, tableName, range, maxSplits):
+        """
+        Parameters:
+         - login
+         - tableName
+         - range
+         - maxSplits
+        """
+        pass
 
-  def tableExists(self, login, tableName):
-    """
-    Parameters:
-     - login
-     - tableName
-    """
-    pass
+    def tableExists(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        pass
 
-  def tableIdMap(self, login):
-    """
-    Parameters:
-     - login
-    """
-    pass
+    def tableIdMap(self, login):
+        """
+        Parameters:
+         - login
+        """
+        pass
 
-  def testTableClassLoad(self, login, tableName, className, asTypeName):
-    """
-    Parameters:
-     - login
-     - tableName
-     - className
-     - asTypeName
-    """
-    pass
+    def testTableClassLoad(self, login, tableName, className, asTypeName):
+        """
+        Parameters:
+         - login
+         - tableName
+         - className
+         - asTypeName
+        """
+        pass
 
-  def pingTabletServer(self, login, tserver):
-    """
-    Parameters:
-     - login
-     - tserver
-    """
-    pass
+    def pingTabletServer(self, login, tserver):
+        """
+        Parameters:
+         - login
+         - tserver
+        """
+        pass
 
-  def getActiveScans(self, login, tserver):
-    """
-    Parameters:
-     - login
-     - tserver
-    """
-    pass
+    def getActiveScans(self, login, tserver):
+        """
+        Parameters:
+         - login
+         - tserver
+        """
+        pass
 
-  def getActiveCompactions(self, login, tserver):
-    """
-    Parameters:
-     - login
-     - tserver
-    """
-    pass
+    def getActiveCompactions(self, login, tserver):
+        """
+        Parameters:
+         - login
+         - tserver
+        """
+        pass
 
-  def getSiteConfiguration(self, login):
-    """
-    Parameters:
-     - login
-    """
-    pass
+    def getSiteConfiguration(self, login):
+        """
+        Parameters:
+         - login
+        """
+        pass
 
-  def getSystemConfiguration(self, login):
-    """
-    Parameters:
-     - login
-    """
-    pass
+    def getSystemConfiguration(self, login):
+        """
+        Parameters:
+         - login
+        """
+        pass
 
-  def getTabletServers(self, login):
-    """
-    Parameters:
-     - login
-    """
-    pass
+    def getTabletServers(self, login):
+        """
+        Parameters:
+         - login
+        """
+        pass
 
-  def removeProperty(self, login, property):
-    """
-    Parameters:
-     - login
-     - property
-    """
-    pass
+    def removeProperty(self, login, property):
+        """
+        Parameters:
+         - login
+         - property
+        """
+        pass
 
-  def setProperty(self, login, property, value):
-    """
-    Parameters:
-     - login
-     - property
-     - value
-    """
-    pass
+    def setProperty(self, login, property, value):
+        """
+        Parameters:
+         - login
+         - property
+         - value
+        """
+        pass
 
-  def testClassLoad(self, login, className, asTypeName):
-    """
-    Parameters:
-     - login
-     - className
-     - asTypeName
-    """
-    pass
+    def testClassLoad(self, login, className, asTypeName):
+        """
+        Parameters:
+         - login
+         - className
+         - asTypeName
+        """
+        pass
 
-  def authenticateUser(self, login, user, properties):
-    """
-    Parameters:
-     - login
-     - user
-     - properties
-    """
-    pass
+    def authenticateUser(self, login, user, properties):
+        """
+        Parameters:
+         - login
+         - user
+         - properties
+        """
+        pass
 
-  def changeUserAuthorizations(self, login, user, authorizations):
-    """
-    Parameters:
-     - login
-     - user
-     - authorizations
-    """
-    pass
+    def changeUserAuthorizations(self, login, user, authorizations):
+        """
+        Parameters:
+         - login
+         - user
+         - authorizations
+        """
+        pass
 
-  def changeLocalUserPassword(self, login, user, password):
-    """
-    Parameters:
-     - login
-     - user
-     - password
-    """
-    pass
+    def changeLocalUserPassword(self, login, user, password):
+        """
+        Parameters:
+         - login
+         - user
+         - password
+        """
+        pass
 
-  def createLocalUser(self, login, user, password):
-    """
-    Parameters:
-     - login
-     - user
-     - password
-    """
-    pass
+    def createLocalUser(self, login, user, password):
+        """
+        Parameters:
+         - login
+         - user
+         - password
+        """
+        pass
 
-  def dropLocalUser(self, login, user):
-    """
-    Parameters:
-     - login
-     - user
-    """
-    pass
+    def dropLocalUser(self, login, user):
+        """
+        Parameters:
+         - login
+         - user
+        """
+        pass
 
-  def getUserAuthorizations(self, login, user):
-    """
-    Parameters:
-     - login
-     - user
-    """
-    pass
+    def getUserAuthorizations(self, login, user):
+        """
+        Parameters:
+         - login
+         - user
+        """
+        pass
 
-  def grantSystemPermission(self, login, user, perm):
-    """
-    Parameters:
-     - login
-     - user
-     - perm
-    """
-    pass
+    def grantSystemPermission(self, login, user, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - perm
+        """
+        pass
 
-  def grantTablePermission(self, login, user, table, perm):
-    """
-    Parameters:
-     - login
-     - user
-     - table
-     - perm
-    """
-    pass
+    def grantTablePermission(self, login, user, table, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - table
+         - perm
+        """
+        pass
 
-  def hasSystemPermission(self, login, user, perm):
-    """
-    Parameters:
-     - login
-     - user
-     - perm
-    """
-    pass
+    def hasSystemPermission(self, login, user, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - perm
+        """
+        pass
 
-  def hasTablePermission(self, login, user, table, perm):
-    """
-    Parameters:
-     - login
-     - user
-     - table
-     - perm
-    """
-    pass
+    def hasTablePermission(self, login, user, table, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - table
+         - perm
+        """
+        pass
 
-  def listLocalUsers(self, login):
-    """
-    Parameters:
-     - login
-    """
-    pass
+    def listLocalUsers(self, login):
+        """
+        Parameters:
+         - login
+        """
+        pass
 
-  def revokeSystemPermission(self, login, user, perm):
-    """
-    Parameters:
-     - login
-     - user
-     - perm
-    """
-    pass
+    def revokeSystemPermission(self, login, user, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - perm
+        """
+        pass
 
-  def revokeTablePermission(self, login, user, table, perm):
-    """
-    Parameters:
-     - login
-     - user
-     - table
-     - perm
-    """
-    pass
+    def revokeTablePermission(self, login, user, table, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - table
+         - perm
+        """
+        pass
 
-  def grantNamespacePermission(self, login, user, namespaceName, perm):
-    """
-    Parameters:
-     - login
-     - user
-     - namespaceName
-     - perm
-    """
-    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 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 revokeNamespacePermission(self, login, user, namespaceName, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - namespaceName
+         - perm
+        """
+        pass
 
-  def createBatchScanner(self, login, tableName, options):
-    """
-    Parameters:
-     - login
-     - tableName
-     - options
-    """
-    pass
+    def createBatchScanner(self, login, tableName, options):
+        """
+        Parameters:
+         - login
+         - tableName
+         - options
+        """
+        pass
 
-  def createScanner(self, login, tableName, options):
-    """
-    Parameters:
-     - login
-     - tableName
-     - options
-    """
-    pass
+    def createScanner(self, login, tableName, options):
+        """
+        Parameters:
+         - login
+         - tableName
+         - options
+        """
+        pass
 
-  def hasNext(self, scanner):
-    """
-    Parameters:
-     - scanner
-    """
-    pass
+    def hasNext(self, scanner):
+        """
+        Parameters:
+         - scanner
+        """
+        pass
 
-  def nextEntry(self, scanner):
-    """
-    Parameters:
-     - scanner
-    """
-    pass
+    def nextEntry(self, scanner):
+        """
+        Parameters:
+         - scanner
+        """
+        pass
 
-  def nextK(self, scanner, k):
-    """
-    Parameters:
-     - scanner
-     - k
-    """
-    pass
+    def nextK(self, scanner, k):
+        """
+        Parameters:
+         - scanner
+         - k
+        """
+        pass
 
-  def closeScanner(self, scanner):
-    """
-    Parameters:
-     - scanner
-    """
-    pass
+    def closeScanner(self, scanner):
+        """
+        Parameters:
+         - scanner
+        """
+        pass
 
-  def updateAndFlush(self, login, tableName, cells):
-    """
-    Parameters:
-     - login
-     - tableName
-     - cells
-    """
-    pass
+    def updateAndFlush(self, login, tableName, cells):
+        """
+        Parameters:
+         - login
+         - tableName
+         - cells
+        """
+        pass
 
-  def createWriter(self, login, tableName, opts):
-    """
-    Parameters:
-     - login
-     - tableName
-     - opts
-    """
-    pass
+    def createWriter(self, login, tableName, opts):
+        """
+        Parameters:
+         - login
+         - tableName
+         - opts
+        """
+        pass
 
-  def update(self, writer, cells):
-    """
-    Parameters:
-     - writer
-     - cells
-    """
-    pass
+    def update(self, writer, cells):
+        """
+        Parameters:
+         - writer
+         - cells
+        """
+        pass
 
-  def flush(self, writer):
-    """
-    Parameters:
-     - writer
-    """
-    pass
+    def flush(self, writer):
+        """
+        Parameters:
+         - writer
+        """
+        pass
 
-  def closeWriter(self, writer):
-    """
-    Parameters:
-     - writer
-    """
-    pass
+    def closeWriter(self, writer):
+        """
+        Parameters:
+         - writer
+        """
+        pass
 
-  def updateRowConditionally(self, login, tableName, row, updates):
-    """
-    Parameters:
-     - login
-     - tableName
-     - row
-     - updates
-    """
-    pass
+    def updateRowConditionally(self, login, tableName, row, updates):
+        """
+        Parameters:
+         - login
+         - tableName
+         - row
+         - updates
+        """
+        pass
 
-  def createConditionalWriter(self, login, tableName, options):
-    """
-    Parameters:
-     - login
-     - tableName
-     - options
-    """
-    pass
+    def createConditionalWriter(self, login, tableName, options):
+        """
+        Parameters:
+         - login
+         - tableName
+         - options
+        """
+        pass
 
-  def updateRowsConditionally(self, conditionalWriter, updates):
-    """
-    Parameters:
-     - conditionalWriter
-     - updates
-    """
-    pass
+    def updateRowsConditionally(self, conditionalWriter, updates):
+        """
+        Parameters:
+         - conditionalWriter
+         - updates
+        """
+        pass
 
-  def closeConditionalWriter(self, conditionalWriter):
-    """
-    Parameters:
-     - conditionalWriter
-    """
-    pass
+    def closeConditionalWriter(self, conditionalWriter):
+        """
+        Parameters:
+         - conditionalWriter
+        """
+        pass
 
-  def getRowRange(self, row):
-    """
-    Parameters:
-     - row
-    """
-    pass
+    def getRowRange(self, row):
+        """
+        Parameters:
+         - row
+        """
+        pass
 
-  def getFollowing(self, key, part):
-    """
-    Parameters:
-     - key
-     - part
-    """
-    pass
+    def getFollowing(self, key, part):
+        """
+        Parameters:
+         - key
+         - part
+        """
+        pass
 
-  def systemNamespace(self):
-    pass
+    def systemNamespace(self):
+        pass
 
-  def defaultNamespace(self):
-    pass
+    def defaultNamespace(self):
+        pass
 
-  def listNamespaces(self, login):
-    """
-    Parameters:
-     - login
-    """
-    pass
+    def listNamespaces(self, login):
+        """
+        Parameters:
+         - login
+        """
+        pass
 
-  def namespaceExists(self, login, namespaceName):
-    """
-    Parameters:
-     - login
-     - namespaceName
-    """
-    pass
+    def namespaceExists(self, login, namespaceName):
+        """
+        Parameters:
+         - login
+         - namespaceName
+        """
+        pass
 
-  def createNamespace(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 deleteNamespace(self, login, namespaceName):
+        """
+        Parameters:
+         - login
+         - namespaceName
+        """
+        pass
 
-  def renameNamespace(self, login, oldNamespaceName, newNamespaceName):
-    """
-    Parameters:
-     - login
-     - oldNamespaceName
-     - newNamespaceName
-    """
-    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 setNamespaceProperty(self, login, namespaceName, property, value):
+        """
+        Parameters:
+         - login
+         - namespaceName
+         - property
+         - value
+        """
+        pass
 
-  def removeNamespaceProperty(self, login, namespaceName, property):
-    """
-    Parameters:
-     - login
-     - namespaceName
-     - property
-    """
-    pass
+    def removeNamespaceProperty(self, login, namespaceName, property):
+        """
+        Parameters:
+         - login
+         - namespaceName
+         - property
+        """
+        pass
 
-  def getNamespaceProperties(self, login, namespaceName):
-    """
-    Parameters:
-     - login
-     - namespaceName
-    """
-    pass
+    def getNamespaceProperties(self, login, namespaceName):
+        """
+        Parameters:
+         - login
+         - namespaceName
+        """
+        pass
 
-  def namespaceIdMap(self, login):
-    """
-    Parameters:
-     - login
-    """
-    pass
+    def namespaceIdMap(self, login):
+        """
+        Parameters:
+         - login
+        """
+        pass
 
-  def attachNamespaceIterator(self, login, namespaceName, setting, scopes):
-    """
-    Parameters:
-     - login
-     - namespaceName
-     - setting
-     - scopes
-    """
-    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 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 getNamespaceIteratorSetting(self, login, namespaceName, name, scope):
+        """
+        Parameters:
+         - login
+         - namespaceName
+         - name
+         - scope
+        """
+        pass
 
-  def listNamespaceIterators(self, login, namespaceName):
-    """
-    Parameters:
-     - login
-     - namespaceName
-    """
-    pass
+    def listNamespaceIterators(self, login, namespaceName):
+        """
+        Parameters:
+         - login
+         - namespaceName
+        """
+        pass
 
-  def checkNamespaceIteratorConflicts(self, login, namespaceName, setting, scopes):
-    """
-    Parameters:
-     - login
-     - namespaceName
-     - setting
-     - scopes
-    """
-    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 addNamespaceConstraint(self, login, namespaceName, constraintClassName):
+        """
+        Parameters:
+         - login
+         - namespaceName
+         - constraintClassName
+        """
+        pass
 
-  def removeNamespaceConstraint(self, login, namespaceName, id):
-    """
-    Parameters:
-     - login
-     - namespaceName
-     - id
-    """
-    pass
+    def removeNamespaceConstraint(self, login, namespaceName, id):
+        """
+        Parameters:
+         - login
+         - namespaceName
+         - id
+        """
+        pass
 
-  def listNamespaceConstraints(self, login, namespaceName):
-    """
-    Parameters:
-     - login
-     - namespaceName
-    """
-    pass
+    def listNamespaceConstraints(self, login, namespaceName):
+        """
+        Parameters:
+         - login
+         - namespaceName
+        """
+        pass
 
-  def testNamespaceClassLoad(self, login, namespaceName, className, asTypeName):
-    """
-    Parameters:
-     - login
-     - namespaceName
-     - className
-     - asTypeName
-    """
-    pass
+    def testNamespaceClassLoad(self, login, namespaceName, className, asTypeName):
+        """
+        Parameters:
+         - login
+         - namespaceName
+         - className
+         - asTypeName
+        """
+        pass
 
 
 class Client(Iface):
-  def __init__(self, iprot, oprot=None):
-    self._iprot = self._oprot = iprot
-    if oprot is not None:
-      self._oprot = oprot
-    self._seqid = 0
+    def __init__(self, iprot, oprot=None):
+        self._iprot = self._oprot = iprot
+        if oprot is not None:
+            self._oprot = oprot
+        self._seqid = 0
 
-  def login(self, principal, loginProperties):
+    def login(self, principal, loginProperties):
+        """
+        Parameters:
+         - principal
+         - loginProperties
+        """
+        self.send_login(principal, loginProperties)
+        return self.recv_login()
+
+    def send_login(self, principal, loginProperties):
+        self._oprot.writeMessageBegin('login', TMessageType.CALL, self._seqid)
+        args = login_args()
+        args.principal = principal
+        args.loginProperties = loginProperties
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_login(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = login_result()
+        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")
+
+    def addConstraint(self, login, tableName, constraintClassName):
+        """
+        Parameters:
+         - login
+         - tableName
+         - constraintClassName
+        """
+        self.send_addConstraint(login, tableName, constraintClassName)
+        return self.recv_addConstraint()
+
+    def send_addConstraint(self, login, tableName, constraintClassName):
+        self._oprot.writeMessageBegin('addConstraint', TMessageType.CALL, self._seqid)
+        args = addConstraint_args()
+        args.login = login
+        args.tableName = tableName
+        args.constraintClassName = constraintClassName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_addConstraint(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = addConstraint_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, "addConstraint failed: unknown result")
+
+    def addSplits(self, login, tableName, splits):
+        """
+        Parameters:
+         - login
+         - tableName
+         - splits
+        """
+        self.send_addSplits(login, tableName, splits)
+        self.recv_addSplits()
+
+    def send_addSplits(self, login, tableName, splits):
+        self._oprot.writeMessageBegin('addSplits', TMessageType.CALL, self._seqid)
+        args = addSplits_args()
+        args.login = login
+        args.tableName = tableName
+        args.splits = splits
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_addSplits(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = addSplits_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 attachIterator(self, login, tableName, setting, scopes):
+        """
+        Parameters:
+         - login
+         - tableName
+         - setting
+         - scopes
+        """
+        self.send_attachIterator(login, tableName, setting, scopes)
+        self.recv_attachIterator()
+
+    def send_attachIterator(self, login, tableName, setting, scopes):
+        self._oprot.writeMessageBegin('attachIterator', TMessageType.CALL, self._seqid)
+        args = attachIterator_args()
+        args.login = login
+        args.tableName = tableName
+        args.setting = setting
+        args.scopes = scopes
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_attachIterator(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = attachIterator_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 checkIteratorConflicts(self, login, tableName, setting, scopes):
+        """
+        Parameters:
+         - login
+         - tableName
+         - setting
+         - scopes
+        """
+        self.send_checkIteratorConflicts(login, tableName, setting, scopes)
+        self.recv_checkIteratorConflicts()
+
+    def send_checkIteratorConflicts(self, login, tableName, setting, scopes):
+        self._oprot.writeMessageBegin('checkIteratorConflicts', TMessageType.CALL, self._seqid)
+        args = checkIteratorConflicts_args()
+        args.login = login
+        args.tableName = tableName
+        args.setting = setting
+        args.scopes = scopes
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_checkIteratorConflicts(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = checkIteratorConflicts_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 clearLocatorCache(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        self.send_clearLocatorCache(login, tableName)
+        self.recv_clearLocatorCache()
+
+    def send_clearLocatorCache(self, login, tableName):
+        self._oprot.writeMessageBegin('clearLocatorCache', TMessageType.CALL, self._seqid)
+        args = clearLocatorCache_args()
+        args.login = login
+        args.tableName = tableName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_clearLocatorCache(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = clearLocatorCache_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.ouch1 is not None:
+            raise result.ouch1
+        return
+
+    def cloneTable(self, login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude):
+        """
+        Parameters:
+         - login
+         - tableName
+         - newTableName
+         - flush
+         - propertiesToSet
+         - propertiesToExclude
+        """
+        self.send_cloneTable(login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude)
+        self.recv_cloneTable()
+
+    def send_cloneTable(self, login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude):
+        self._oprot.writeMessageBegin('cloneTable', TMessageType.CALL, self._seqid)
+        args = cloneTable_args()
+        args.login = login
+        args.tableName = tableName
+        args.newTableName = newTableName
+        args.flush = flush
+        args.propertiesToSet = propertiesToSet
+        args.propertiesToExclude = propertiesToExclude
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_cloneTable(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = cloneTable_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 compactTable(self, login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy):
+        """
+        Parameters:
+         - login
+         - tableName
+         - startRow
+         - endRow
+         - iterators
+         - flush
+         - wait
+         - compactionStrategy
+        """
+        self.send_compactTable(login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy)
+        self.recv_compactTable()
+
+    def send_compactTable(self, login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy):
+        self._oprot.writeMessageBegin('compactTable', TMessageType.CALL, self._seqid)
+        args = compactTable_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(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_compactTable(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = compactTable_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 cancelCompaction(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        self.send_cancelCompaction(login, tableName)
+        self.recv_cancelCompaction()
+
+    def send_cancelCompaction(self, login, tableName):
+        self._oprot.writeMessageBegin('cancelCompaction', TMessageType.CALL, self._seqid)
+        args = cancelCompaction_args()
+        args.login = login
+        args.tableName = tableName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_cancelCompaction(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = cancelCompaction_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 createTable(self, login, tableName, versioningIter, type):
+        """
+        Parameters:
+         - login
+         - tableName
+         - versioningIter
+         - type
+        """
+        self.send_createTable(login, tableName, versioningIter, type)
+        self.recv_createTable()
+
+    def send_createTable(self, login, tableName, versioningIter, type):
+        self._oprot.writeMessageBegin('createTable', TMessageType.CALL, self._seqid)
+        args = createTable_args()
+        args.login = login
+        args.tableName = tableName
+        args.versioningIter = versioningIter
+        args.type = type
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_createTable(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = createTable_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 deleteTable(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        self.send_deleteTable(login, tableName)
+        self.recv_deleteTable()
+
+    def send_deleteTable(self, login, tableName):
+        self._oprot.writeMessageBegin('deleteTable', TMessageType.CALL, self._seqid)
+        args = deleteTable_args()
+        args.login = login
+        args.tableName = tableName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_deleteTable(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = deleteTable_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 deleteRows(self, login, tableName, startRow, endRow):
+        """
+        Parameters:
+         - login
+         - tableName
+         - startRow
+         - endRow
+        """
+        self.send_deleteRows(login, tableName, startRow, endRow)
+        self.recv_deleteRows()
+
+    def send_deleteRows(self, login, tableName, startRow, endRow):
+        self._oprot.writeMessageBegin('deleteRows', TMessageType.CALL, self._seqid)
+        args = deleteRows_args()
+        args.login = login
+        args.tableName = tableName
+        args.startRow = startRow
+        args.endRow = endRow
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_deleteRows(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = deleteRows_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 exportTable(self, login, tableName, exportDir):
+        """
+        Parameters:
+         - login
+         - tableName
+         - exportDir
+        """
+        self.send_exportTable(login, tableName, exportDir)
+        self.recv_exportTable()
+
+    def send_exportTable(self, login, tableName, exportDir):
+        self._oprot.writeMessageBegin('exportTable', TMessageType.CALL, self._seqid)
+        args = exportTable_args()
+        args.login = login
+        args.tableName = tableName
+        args.exportDir = exportDir
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_exportTable(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = exportTable_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 flushTable(self, login, tableName, startRow, endRow, wait):
+        """
+        Parameters:
+         - login
+         - tableName
+         - startRow
+         - endRow
+         - wait
+        """
+        self.send_flushTable(login, tableName, startRow, endRow, wait)
+        self.recv_flushTable()
+
+    def send_flushTable(self, login, tableName, startRow, endRow, wait):
+        self._oprot.writeMessageBegin('flushTable', TMessageType.CALL, self._seqid)
+        args = flushTable_args()
+        args.login = login
+        args.tableName = tableName
+        args.startRow = startRow
+        args.endRow = endRow
+        args.wait = wait
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_flushTable(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = flushTable_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 getDiskUsage(self, login, tables):
+        """
+        Parameters:
+         - login
+         - tables
+        """
+        self.send_getDiskUsage(login, tables)
+        return self.recv_getDiskUsage()
+
+    def send_getDiskUsage(self, login, tables):
+        self._oprot.writeMessageBegin('getDiskUsage', TMessageType.CALL, self._seqid)
+        args = getDiskUsage_args()
+        args.login = login
+        args.tables = tables
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getDiskUsage(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getDiskUsage_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, "getDiskUsage failed: unknown result")
+
+    def getLocalityGroups(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        self.send_getLocalityGroups(login, tableName)
+        return self.recv_getLocalityGroups()
+
+    def send_getLocalityGroups(self, login, tableName):
+        self._oprot.writeMessageBegin('getLocalityGroups', TMessageType.CALL, self._seqid)
+        args = getLocalityGroups_args()
+        args.login = login
+        args.tableName = tableName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getLocalityGroups(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getLocalityGroups_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, "getLocalityGroups failed: unknown result")
+
+    def getIteratorSetting(self, login, tableName, iteratorName, scope):
+        """
+        Parameters:
+         - login
+         - tableName
+         - iteratorName
+         - scope
+        """
+        self.send_getIteratorSetting(login, tableName, iteratorName, scope)
+        return self.recv_getIteratorSetting()
+
+    def send_getIteratorSetting(self, login, tableName, iteratorName, scope):
+        self._oprot.writeMessageBegin('getIteratorSetting', TMessageType.CALL, self._seqid)
+        args = getIteratorSetting_args()
+        args.login = login
+        args.tableName = tableName
+        args.iteratorName = iteratorName
+        args.scope = scope
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getIteratorSetting(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getIteratorSetting_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, "getIteratorSetting failed: unknown result")
+
+    def getMaxRow(self, login, tableName, auths, startRow, startInclusive, endRow, endInclusive):
+        """
+        Parameters:
+         - login
+         - tableName
+         - auths
+         - startRow
+         - startInclusive
+         - endRow
+         - endInclusive
+        """
+        self.send_getMaxRow(login, tableName, auths, startRow, startInclusive, endRow, endInclusive)
+        return self.recv_getMaxRow()
+
+    def send_getMaxRow(self, login, tableName, auths, startRow, startInclusive, endRow, endInclusive):
+        self._oprot.writeMessageBegin('getMaxRow', TMessageType.CALL, self._seqid)
+        args = getMaxRow_args()
+        args.login = login
+        args.tableName = tableName
+        args.auths = auths
+        args.startRow = startRow
+        args.startInclusive = startInclusive
+        args.endRow = endRow
+        args.endInclusive = endInclusive
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getMaxRow(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getMaxRow_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, "getMaxRow failed: unknown result")
+
+    def getTableProperties(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        self.send_getTableProperties(login, tableName)
+        return self.recv_getTableProperties()
+
+    def send_getTableProperties(self, login, tableName):
+        self._oprot.writeMessageBegin('getTableProperties', TMessageType.CALL, self._seqid)
+        args = getTableProperties_args()
+        args.login = login
+        args.tableName = tableName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getTableProperties(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getTableProperties_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, "getTableProperties failed: unknown result")
+
+    def importDirectory(self, login, tableName, importDir, failureDir, setTime):
+        """
+        Parameters:
+         - login
+         - tableName
+         - importDir
+         - failureDir
+         - setTime
+        """
+        self.send_importDirectory(login, tableName, importDir, failureDir, setTime)
+        self.recv_importDirectory()
+
+    def send_importDirectory(self, login, tableName, importDir, failureDir, setTime):
+        self._oprot.writeMessageBegin('importDirectory', TMessageType.CALL, self._seqid)
+        args = importDirectory_args()
+        args.login = login
+        args.tableName = tableName
+        args.importDir = importDir
+        args.failureDir = failureDir
+        args.setTime = setTime
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_importDirectory(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = importDirectory_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.ouch1 is not None:
+            raise result.ouch1
+        if result.ouch3 is not None:
+            raise result.ouch3
+        if result.ouch4 is not None:
+            raise result.ouch4
+        return
+
+    def importTable(self, login, tableName, importDir):
+        """
+        Parameters:
+         - login
+         - tableName
+         - importDir
+        """
+        self.send_importTable(login, tableName, importDir)
+        self.recv_importTable()
+
+    def send_importTable(self, login, tableName, importDir):
+        self._oprot.writeMessageBegin('importTable', TMessageType.CALL, self._seqid)
+        args = importTable_args()
+        args.login = login
+        args.tableName = tableName
+        args.importDir = importDir
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_importTable(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = importTable_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 listSplits(self, login, tableName, maxSplits):
+        """
+        Parameters:
+         - login
+         - tableName
+         - maxSplits
+        """
+        self.send_listSplits(login, tableName, maxSplits)
+        return self.recv_listSplits()
+
+    def send_listSplits(self, login, tableName, maxSplits):
+        self._oprot.writeMessageBegin('listSplits', TMessageType.CALL, self._seqid)
+        args = listSplits_args()
+        args.login = login
+        args.tableName = tableName
+        args.maxSplits = maxSplits
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_listSplits(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = listSplits_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, "listSplits failed: unknown result")
+
+    def listTables(self, login):
+        """
+        Parameters:
+         - login
+        """
+        self.send_listTables(login)
+        return self.recv_listTables()
+
+    def send_listTables(self, login):
+        self._oprot.writeMessageBegin('listTables', TMessageType.CALL, self._seqid)
+        args = listTables_args()
+        args.login = login
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_listTables(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = listTables_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.success is not None:
+            return result.success
+        raise TApplicationException(TApplicationException.MISSING_RESULT, "listTables failed: unknown result")
+
+    def listIterators(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        self.send_listIterators(login, tableName)
+        return self.recv_listIterators()
+
+    def send_listIterators(self, login, tableName):
+        self._oprot.writeMessageBegin('listIterators', TMessageType.CALL, self._seqid)
+        args = listIterators_args()
+        args.login = login
+        args.tableName = tableName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_listIterators(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = listIterators_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, "listIterators failed: unknown result")
+
+    def listConstraints(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        self.send_listConstraints(login, tableName)
+        return self.recv_listConstraints()
+
+    def send_listConstraints(self, login, tableName):
+        self._oprot.writeMessageBegin('listConstraints', TMessageType.CALL, self._seqid)
+        args = listConstraints_args()
+        args.login = login
+        args.tableName = tableName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_listConstraints(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = listConstraints_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, "listConstraints failed: unknown result")
+
+    def mergeTablets(self, login, tableName, startRow, endRow):
+        """
+        Parameters:
+         - login
+         - tableName
+         - startRow
+         - endRow
+        """
+        self.send_mergeTablets(login, tableName, startRow, endRow)
+        self.recv_mergeTablets()
+
+    def send_mergeTablets(self, login, tableName, startRow, endRow):
+        self._oprot.writeMessageBegin('mergeTablets', TMessageType.CALL, self._seqid)
+        args = mergeTablets_args()
+        args.login = login
+        args.tableName = tableName
+        args.startRow = startRow
+        args.endRow = endRow
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_mergeTablets(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = mergeTablets_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 offlineTable(self, login, tableName, wait):
+        """
+        Parameters:
+         - login
+         - tableName
+         - wait
+        """
+        self.send_offlineTable(login, tableName, wait)
+        self.recv_offlineTable()
+
+    def send_offlineTable(self, login, tableName, wait):
+        self._oprot.writeMessageBegin('offlineTable', TMessageType.CALL, self._seqid)
+        args = offlineTable_args()
+        args.login = login
+        args.tableName = tableName
+        args.wait = wait
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_offlineTable(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = offlineTable_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 onlineTable(self, login, tableName, wait):
+        """
+        Parameters:
+         - login
+         - tableName
+         - wait
+        """
+        self.send_onlineTable(login, tableName, wait)
+        self.recv_onlineTable()
+
+    def send_onlineTable(self, login, tableName, wait):
+        self._oprot.writeMessageBegin('onlineTable', TMessageType.CALL, self._seqid)
+        args = onlineTable_args()
+        args.login = login
+        args.tableName = tableName
+        args.wait = wait
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_onlineTable(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = onlineTable_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 removeConstraint(self, login, tableName, constraint):
+        """
+        Parameters:
+         - login
+         - tableName
+         - constraint
+        """
+        self.send_removeConstraint(login, tableName, constraint)
+        self.recv_removeConstraint()
+
+    def send_removeConstraint(self, login, tableName, constraint):
+        self._oprot.writeMessageBegin('removeConstraint', TMessageType.CALL, self._seqid)
+        args = removeConstraint_args()
+        args.login = login
+        args.tableName = tableName
+        args.constraint = constraint
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_removeConstraint(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = removeConstraint_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 removeIterator(self, login, tableName, iterName, scopes):
+        """
+        Parameters:
+         - login
+         - tableName
+         - iterName
+         - scopes
+        """
+        self.send_removeIterator(login, tableName, iterName, scopes)
+        self.recv_removeIterator()
+
+    def send_removeIterator(self, login, tableName, iterName, scopes):
+        self._oprot.writeMessageBegin('removeIterator', TMessageType.CALL, self._seqid)
+        args = removeIterator_args()
+        args.login = login
+        args.tableName = tableName
+        args.iterName = iterName
+        args.scopes = scopes
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_removeIterator(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = removeIterator_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 removeTableProperty(self, login, tableName, property):
+        """
+        Parameters:
+         - login
+         - tableName
+         - property
+        """
+        self.send_removeTableProperty(login, tableName, property)
+        self.recv_removeTableProperty()
+
+    def send_removeTableProperty(self, login, tableName, property):
+        self._oprot.writeMessageBegin('removeTableProperty', TMessageType.CALL, self._seqid)
+        args = removeTableProperty_args()
+        args.login = login
+        args.tableName = tableName
+        args.property = property
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_removeTableProperty(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = removeTableProperty_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 renameTable(self, login, oldTableName, newTableName):
+        """
+        Parameters:
+         - login
+         - oldTableName
+         - newTableName
+        """
+        self.send_renameTable(login, oldTableName, newTableName)
+        self.recv_renameTable()
+
+    def send_renameTable(self, login, oldTableName, newTableName):
+        self._oprot.writeMessageBegin('renameTable', TMessageType.CALL, self._seqid)
+        args = renameTable_args()
+        args.login = login
+        args.oldTableName = oldTableName
+        args.newTableName = newTableName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_renameTable(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = renameTable_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 setLocalityGroups(self, login, tableName, groups):
+        """
+        Parameters:
+         - login
+         - tableName
+         - groups
+        """
+        self.send_setLocalityGroups(login, tableName, groups)
+        self.recv_setLocalityGroups()
+
+    def send_setLocalityGroups(self, login, tableName, groups):
+        self._oprot.writeMessageBegin('setLocalityGroups', TMessageType.CALL, self._seqid)
+        args = setLocalityGroups_args()
+        args.login = login
+        args.tableName = tableName
+        args.groups = groups
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_setLocalityGroups(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = setLocalityGroups_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 setTableProperty(self, login, tableName, property, value):
+        """
+        Parameters:
+         - login
+         - tableName
+         - property
+         - value
+        """
+        self.send_setTableProperty(login, tableName, property, value)
+        self.recv_setTableProperty()
+
+    def send_setTableProperty(self, login, tableName, property, value):
+        self._oprot.writeMessageBegin('setTableProperty', TMessageType.CALL, self._seqid)
+        args = setTableProperty_args()
+        args.login = login
+        args.tableName = tableName
+        args.property = property
+        args.value = value
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_setTableProperty(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = setTableProperty_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 splitRangeByTablets(self, login, tableName, range, maxSplits):
+        """
+        Parameters:
+         - login
+         - tableName
+         - range
+         - maxSplits
+        """
+        self.send_splitRangeByTablets(login, tableName, range, maxSplits)
+        return self.recv_splitRangeByTablets()
+
+    def send_splitRangeByTablets(self, login, tableName, range, maxSplits):
+        self._oprot.writeMessageBegin('splitRangeByTablets', TMessageType.CALL, self._seqid)
+        args = splitRangeByTablets_args()
+        args.login = login
+        args.tableName = tableName
+        args.range = range
+        args.maxSplits = maxSplits
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_splitRangeByTablets(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = splitRangeByTablets_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, "splitRangeByTablets failed: unknown result")
+
+    def tableExists(self, login, tableName):
+        """
+        Parameters:
+         - login
+         - tableName
+        """
+        self.send_tableExists(login, tableName)
+        return self.recv_tableExists()
+
+    def send_tableExists(self, login, tableName):
+        self._oprot.writeMessageBegin('tableExists', TMessageType.CALL, self._seqid)
+        args = tableExists_args()
+        args.login = login
+        args.tableName = tableName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_tableExists(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = tableExists_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.success is not None:
+            return result.success
+        raise TApplicationException(TApplicationException.MISSING_RESULT, "tableExists failed: unknown result")
+
+    def tableIdMap(self, login):
+        """
+        Parameters:
+         - login
+        """
+        self.send_tableIdMap(login)
+        return self.recv_tableIdMap()
+
+    def send_tableIdMap(self, login):
+        self._oprot.writeMessageBegin('tableIdMap', TMessageType.CALL, self._seqid)
+        args = tableIdMap_args()
+        args.login = login
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_tableIdMap(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = tableIdMap_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.success is not None:
+            return result.success
+        raise TApplicationException(TApplicationException.MISSING_RESULT, "tableIdMap failed: unknown result")
+
+    def testTableClassLoad(self, login, tableName, className, asTypeName):
+        """
+        Parameters:
+         - login
+         - tableName
+         - className
+         - asTypeName
+        """
+        self.send_testTableClassLoad(login, tableName, className, asTypeName)
+        return self.recv_testTableClassLoad()
+
+    def send_testTableClassLoad(self, login, tableName, className, asTypeName):
+        self._oprot.writeMessageBegin('testTableClassLoad', TMessageType.CALL, self._seqid)
+        args = testTableClassLoad_args()
+        args.login = login
+        args.tableName = tableName
+        args.className = className
+        args.asTypeName = asTypeName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_testTableClassLoad(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = testTableClassLoad_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, "testTableClassLoad failed: unknown result")
+
+    def pingTabletServer(self, login, tserver):
+        """
+        Parameters:
+         - login
+         - tserver
+        """
+        self.send_pingTabletServer(login, tserver)
+        self.recv_pingTabletServer()
+
+    def send_pingTabletServer(self, login, tserver):
+        self._oprot.writeMessageBegin('pingTabletServer', TMessageType.CALL, self._seqid)
+        args = pingTabletServer_args()
+        args.login = login
+        args.tserver = tserver
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_pingTabletServer(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = pingTabletServer_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 getActiveScans(self, login, tserver):
+        """
+        Parameters:
+         - login
+         - tserver
+        """
+        self.send_getActiveScans(login, tserver)
+        return self.recv_getActiveScans()
+
+    def send_getActiveScans(self, login, tserver):
+        self._oprot.writeMessageBegin('getActiveScans', TMessageType.CALL, self._seqid)
+        args = getActiveScans_args()
+        args.login = login
+        args.tserver = tserver
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getActiveScans(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getActiveScans_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, "getActiveScans failed: unknown result")
+
+    def getActiveCompactions(self, login, tserver):
+        """
+        Parameters:
+         - login
+         - tserver
+        """
+        self.send_getActiveCompactions(login, tserver)
+        return self.recv_getActiveCompactions()
+
+    def send_getActiveCompactions(self, login, tserver):
+        self._oprot.writeMessageBegin('getActiveCompactions', TMessageType.CALL, self._seqid)
+        args = getActiveCompactions_args()
+        args.login = login
+        args.tserver = tserver
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getActiveCompactions(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getActiveCompactions_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, "getActiveCompactions failed: unknown result")
+
+    def getSiteConfiguration(self, login):
+        """
+        Parameters:
+         - login
+        """
+        self.send_getSiteConfiguration(login)
+        return self.recv_getSiteConfiguration()
+
+    def send_getSiteConfiguration(self, login):
+        self._oprot.writeMessageBegin('getSiteConfiguration', TMessageType.CALL, self._seqid)
+        args = getSiteConfiguration_args()
+        args.login = login
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getSiteConfiguration(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getSiteConfiguration_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, "getSiteConfiguration failed: unknown result")
+
+    def getSystemConfiguration(self, login):
+        """
+        Parameters:
+         - login
+        """
+        self.send_getSystemConfiguration(login)
+        return self.recv_getSystemConfiguration()
+
+    def send_getSystemConfiguration(self, login):
+        self._oprot.writeMessageBegin('getSystemConfiguration', TMessageType.CALL, self._seqid)
+        args = getSystemConfiguration_args()
+        args.login = login
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getSystemConfiguration(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getSystemConfiguration_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, "getSystemConfiguration failed: unknown result")
+
+    def getTabletServers(self, login):
+        """
+        Parameters:
+         - login
+        """
+        self.send_getTabletServers(login)
+        return self.recv_getTabletServers()
+
+    def send_getTabletServers(self, login):
+        self._oprot.writeMessageBegin('getTabletServers', TMessageType.CALL, self._seqid)
+        args = getTabletServers_args()
+        args.login = login
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getTabletServers(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getTabletServers_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.success is not None:
+            return result.success
+        raise TApplicationException(TApplicationException.MISSING_RESULT, "getTabletServers failed: unknown result")
+
+    def removeProperty(self, login, property):
+        """
+        Parameters:
+         - login
+         - property
+        """
+        self.send_removeProperty(login, property)
+        self.recv_removeProperty()
+
+    def send_removeProperty(self, login, property):
+        self._oprot.writeMessageBegin('removeProperty', TMessageType.CALL, self._seqid)
+        args = removeProperty_args()
+        args.login = login
+        args.property = property
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_removeProperty(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = removeProperty_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 setProperty(self, login, property, value):
+        """
+        Parameters:
+         - login
+         - property
+         - value
+        """
+        self.send_setProperty(login, property, value)
+        self.recv_setProperty()
+
+    def send_setProperty(self, login, property, value):
+        self._oprot.writeMessageBegin('setProperty', TMessageType.CALL, self._seqid)
+        args = setProperty_args()
+        args.login = login
+        args.property = property
+        args.value = value
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_setProperty(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = setProperty_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 testClassLoad(self, login, className, asTypeName):
+        """
+        Parameters:
+         - login
+         - className
+         - asTypeName
+        """
+        self.send_testClassLoad(login, className, asTypeName)
+        return self.recv_testClassLoad()
+
+    def send_testClassLoad(self, login, className, asTypeName):
+        self._oprot.writeMessageBegin('testClassLoad', TMessageType.CALL, self._seqid)
+        args = testClassLoad_args()
+        args.login = login
+        args.className = className
+        args.asTypeName = asTypeName
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_testClassLoad(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = testClassLoad_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, "testClassLoad failed: unknown result")
+
+    def authenticateUser(self, login, user, properties):
+        """
+        Parameters:
+         - login
+         - user
+         - properties
+        """
+        self.send_authenticateUser(login, user, properties)
+        return self.recv_authenticateUser()
+
+    def send_authenticateUser(self, login, user, properties):
+        self._oprot.writeMessageBegin('authenticateUser', TMessageType.CALL, self._seqid)
+        args = authenticateUser_args()
+        args.login = login
+        args.user = user
+        args.properties = properties
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_authenticateUser(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = authenticateUser_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, "authenticateUser failed: unknown result")
+
+    def changeUserAuthorizations(self, login, user, authorizations):
+        """
+        Parameters:
+         - login
+         - user
+         - authorizations
+        """
+        self.send_changeUserAuthorizations(login, user, authorizations)
+        self.recv_changeUserAuthorizations()
+
+    def send_changeUserAuthorizations(self, login, user, authorizations):
+        self._oprot.writeMessageBegin('changeUserAuthorizations', TMessageType.CALL, self._seqid)
+        args = changeUserAuthorizations_args()
+        args.login = login
+        args.user = user
+        args.authorizations = authorizations
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_changeUserAuthorizations(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = changeUserAuthorizations_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 changeLocalUserPassword(self, login, user, password):
+        """
+        Parameters:
+         - login
+         - user
+         - password
+        """
+        self.send_changeLocalUserPassword(login, user, password)
+        self.recv_changeLocalUserPassword()
+
+    def send_changeLocalUserPassword(self, login, user, password):
+        self._oprot.writeMessageBegin('changeLocalUserPassword', TMessageType.CALL, self._seqid)
+        args = changeLocalUserPassword_args()
+        args.login = login
+        args.user = user
+        args.password = password
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_changeLocalUserPassword(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = changeLocalUserPassword_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 createLocalUser(self, login, user, password):
+        """
+        Parameters:
+         - login
+         - user
+         - password
+        """
+        self.send_createLocalUser(login, user, password)
+        self.recv_createLocalUser()
+
+    def send_createLocalUser(self, login, user, password):
+        self._oprot.writeMessageBegin('createLocalUser', TMessageType.CALL, self._seqid)
+        args = createLocalUser_args()
+        args.login = login
+        args.user = user
+        args.password = password
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_createLocalUser(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = createLocalUser_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 dropLocalUser(self, login, user):
+        """
+        Parameters:
+         - login
+         - user
+        """
+        self.send_dropLocalUser(login, user)
+        self.recv_dropLocalUser()
+
+    def send_dropLocalUser(self, login, user):
+        self._oprot.writeMessageBegin('dropLocalUser', TMessageType.CALL, self._seqid)
+        args = dropLocalUser_args()
+        args.login = login
+        args.user = user
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_dropLocalUser(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = dropLocalUser_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 getUserAuthorizations(self, login, user):
+        """
+        Parameters:
+         - login
+         - user
+        """
+        self.send_getUserAuthorizations(login, user)
+        return self.recv_getUserAuthorizations()
+
+    def send_getUserAuthorizations(self, login, user):
+        self._oprot.writeMessageBegin('getUserAuthorizations', TMessageType.CALL, self._seqid)
+        args = getUserAuthorizations_args()
+        args.login = login
+        args.user = user
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getUserAuthorizations(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getUserAuthorizations_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, "getUserAuthorizations failed: unknown result")
+
+    def grantSystemPermission(self, login, user, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - perm
+        """
+        self.send_grantSystemPermission(login, user, perm)
+        self.recv_grantSystemPermission()
+
+    def send_grantSystemPermission(self, login, user, perm):
+        self._oprot.writeMessageBegin('grantSystemPermission', TMessageType.CALL, self._seqid)
+        args = grantSystemPermission_args()
+        args.login = login
+        args.user = user
+        args.perm = perm
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_grantSystemPermission(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = grantSystemPermission_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 grantTablePermission(self, login, user, table, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - table
+         - perm
+        """
+        self.send_grantTablePermission(login, user, table, perm)
+        self.recv_grantTablePermission()
+
+    def send_grantTablePermission(self, login, user, table, perm):
+        self._oprot.writeMessageBegin('grantTablePermission', TMessageType.CALL, self._seqid)
+        args = grantTablePermission_args()
+        args.login = login
+        args.user = user
+        args.table = table
+        args.perm = perm
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_grantTablePermission(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = grantTablePermission_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 hasSystemPermission(self, login, user, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - perm
+        """
+        self.send_hasSystemPermission(login, user, perm)
+        return self.recv_hasSystemPermission()
+
+    def send_hasSystemPermission(self, login, user, perm):
+        self._oprot.writeMessageBegin('hasSystemPermission', TMessageType.CALL, self._seqid)
+        args = hasSystemPermission_args()
+        args.login = login
+        args.user = user
+        args.perm = perm
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_hasSystemPermission(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = hasSystemPermission_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, "hasSystemPermission failed: unknown result")
+
+    def hasTablePermission(self, login, user, table, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - table
+         - perm
+        """
+        self.send_hasTablePermission(login, user, table, perm)
+        return self.recv_hasTablePermission()
+
+    def send_hasTablePermission(self, login, user, table, perm):
+        self._oprot.writeMessageBegin('hasTablePermission', TMessageType.CALL, self._seqid)
+        args = hasTablePermission_args()
+        args.login = login
+        args.user = user
+        args.table = table
+        args.perm = perm
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_hasTablePermission(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = hasTablePermission_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, "hasTablePermission failed: unknown result")
+
+    def listLocalUsers(self, login):
+        """
+        Parameters:
+         - login
+        """
+        self.send_listLocalUsers(login)
+        return self.recv_listLocalUsers()
+
+    def send_listLocalUsers(self, login):
+        self._oprot.writeMessageBegin('listLocalUsers', TMessageType.CALL, self._seqid)
+        args = listLocalUsers_args()
+        args.login = login
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_listLocalUsers(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = listLocalUsers_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, "listLocalUsers failed: unknown result")
+
+    def revokeSystemPermission(self, login, user, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - perm
+        """
+        self.send_revokeSystemPermission(login, user, perm)
+        self.recv_revokeSystemPermission()
+
+    def send_revokeSystemPermission(self, login, user, perm):
+        self._oprot.writeMessageBegin('revokeSystemPermission', TMessageType.CALL, self._seqid)
+        args = revokeSystemPermission_args()
+        args.login = login
+        args.user = user
+        args.perm = perm
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_revokeSystemPermission(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = revokeSystemPermission_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 revokeTablePermission(self, login, user, table, perm):
+        """
+        Parameters:
+         - login
+         - user
+         - table
+         - perm
+        """
+        self.send_revokeTablePermission(login, user, table, perm)
+        self.recv_revokeTablePermission()
+
+    def send_revokeTablePermission(self, login, user, table, perm):
+        self._oprot.writeMessageBegin('revokeTablePermission', TMessageType.CALL, self._seqid)
+        args = revokeTablePermission_args()
+        args.login = login
+        args.user = user
+        args.table = table
+        args.perm = perm
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_revokeTablePermission(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = revokeTablePermission_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 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:
+         - login
+         - tableName
+         - options
+        """
+        self.send_createBatchScanner(login, tableName, options)
+        return self.recv_createBatchScanner()
+
+    def send_createBatchScanner(self, login, tableName, options):
+        self._oprot.writeMessageBegin('createBatchScanner', TMessageType.CALL, self._seqid)
+        args = createBatchScanner_args()
+        args.login = login
+        args.tableName = tableName
+        args.options = options
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_createBatchScanner(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = createBatchScanner_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, "createBatchScanner failed: unknown result")
+
+    def createScanner(self, login, tableName, options):
+        """
+        Parameters:
+         - login
+         - tableName
+         - options
+        """
+        self.send_createScanner(login, tableName, options)
+        return self.recv_createScanner()
+
+    def send_createScanner(self, login, tableName, options):
+        self._oprot.writeMessageBegin('createScanner', TMessageType.CALL, self._seqid)
+        args = createScanner_args()
+        args.login = login
+        args.tableName = tableName
+        args.options = options
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_createScanner(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = createScanner_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, "createScanner failed: unknown result")
+
+    def hasNext(self, scanner):
+        """
+        Parameters:
+         - scanner
+        """
+        self.send_hasNext(scanner)
+        return self.recv_hasNext()
+
+    def send_hasNext(self, scanner):
+        self._oprot.writeMessageBegin('hasNext', TMessageType.CALL, self._seqid)
+        args = hasNext_args()
+        args.scanner = scanner
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_hasNext(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = hasNext_result()
+        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")
+
+    def nextEntry(self, scanner):
+        """
+        Parameters:
+         - scanner
+        """
+        self.send_nextEntry(scanner)
+        return self.recv_nextEntry()
+
+    def send_nextEntry(self, scanner):
+        self._oprot.writeMessageBegin('nextEntry', TMessageType.CALL, self._seqid)
+        args = nextEntry_args()
+        args.scanner = scanner
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_nextEntry(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = nextEntry_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, "nextEntry failed: unknown result")
+
+    def nextK(self, scanner, k):
+        """
+        Parameters:
+         - scanner
+         - k
+        """
+        self.send_nextK(scanner, k)
+        return self.recv_nextK()
+
+    def send_nextK(self, scanner, k):
+        self._oprot.writeMessageBegin('nextK', TMessageType.CALL, self._seqid)
+        args = nextK_args()
+        args.scanner = scanner
+        args.k = k
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_nextK(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = nextK_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, "nextK failed: unknown result")
+
+    def closeScanner(self, scanner):
+        """
+        Parameters:
+         - scanner
+        """
+        self.send_closeScanner(scanner)
+        self.recv_closeScanner()
+
+    def send_closeScanner(self, scanner):
+        self._oprot.writeMessageBegin('closeScanner', TMessageType.CALL, self._seqid)
+        args = closeScanner_args()
+        args.scanner = scanner
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_closeScanner(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = closeScanner_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.ouch1 is not None:
+            raise result.ouch1
+        return
+
+    def updateAndFlush(self, login, tableName, cells):
+        """
+        Parameters:
+         - login
+         - tableName
+         - cells
+        """
+        self.send_updateAndFlush(login, tableName, cells)
+        self.recv_updateAndFlush()
+
+    def send_updateAndFlush(self, login, tableName, cells):
+        self._oprot.writeMessageBegin('updateAndFlush', TMessageType.CALL, self._seqid)
+        args = updateAndFlush_args()
+        args.login = login
+        args.tableName = tableName
+        args.cells = cells
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_updateAndFlush(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = updateAndFlush_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.outch1 is not None:
+            raise result.outch1
+        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 createWriter(self, login, tableName, opts):
+        """
+        Parameters:
+         - login
+         - tableName
+         - opts
+        """
+        self.send_createWriter(login, tableName, opts)
+        return self.recv_createWriter()
+
+    def send_createWriter(self, login, tableName, opts):
+        self._oprot.writeMessageBegin('createWriter', TMessageType.CALL, self._seqid)
+        args = createWriter_args()
+        args.login = login
+        args.tableName = tableName
+        args.opts = opts
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_createWriter(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = createWriter_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.success is not None:
+            return result.success
+        if result.outch1 is not None:
+            raise result.outch1
+        if result.ouch2 is not None:
+            raise result.ouch2
+        if result.ouch3 is not None:
+            raise result.ouch3
+        raise TApplicationException(TApplicationException.MISSING_RESULT, "createWriter failed: unknown result")
+
+    def update(self, writer, cells):
+        """
+        Parameters:
+         - writer
+         - cells
+        """
+        self.send_update(writer, cells)
+
+    def send_update(self, writer, cells):
+        self._oprot.writeMessageBegin('update', TMessageType.ONEWAY, self._seqid)
+        args = update_args()
+        args.writer = writer
+        args.cells = cells
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def flush(self, writer):
+        """
+        Parameters:
+         - writer
+        """
+        self.send_flush(writer)
+        self.recv_flush()
+
+    def send_flush(self, writer):
+        self._oprot.writeMessageBegin('flush', TMessageType.CALL, self._seqid)
+        args = flush_args()
+        args.writer = writer
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_flush(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = flush_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 closeWriter(self, writer):
+        """
+        Parameters:
+         - writer
+        """
+        self.send_closeWriter(writer)
+        self.recv_closeWriter()
+
+    def send_closeWriter(self, writer):
+        self._oprot.writeMessageBegin('closeWriter', TMessageType.CALL, self._seqid)
+        args = closeWriter_args()
+        args.writer = writer
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_closeWriter(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = closeWriter_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 updateRowConditionally(self, login, tableName, row, updates):
+        """
+        Parameters:
+         - login
+         - tableName
+         - row
+         - updates
+        """
+        self.send_updateRowConditionally(login, tableName, row, updates)
+        return self.recv_updateRowConditionally()
+
+    def send_updateRowConditionally(self, login, tableName, row, updates):
+        self._oprot.writeMessageBegin('updateRowConditionally', TMessageType.CALL, self._seqid)
+        args = updateRowConditionally_args()
+        args.login = login
+        args.tableName = tableName
+        args.row = row
+        args.updates = updates
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_updateRowConditionally(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = updateRowConditionally_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, "updateRowConditionally failed: unknown result")
+
+    def createConditionalWriter(self, login, tableName, options):
+        """
+        Parameters:
+         - login
+         - tableName
+         - options
+        """
+        self.send_createConditionalWriter(login, tableName, options)
+        return self.recv_createConditionalWriter()
+
+    def send_createConditionalWriter(self, login, tableName, options):
+        self._oprot.writeMessageBegin('createConditionalWriter', TMessageType.CALL, self._seqid)
+        args = createConditionalWriter_args()
+        args.login = login
+        args.tableName = tableName
+        args.options = options
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_createConditionalWriter(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = createConditionalWriter_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, "createConditionalWriter failed: unknown result")
+
+    def updateRowsConditionally(self, conditionalWriter, updates):
+        """
+        Parameters:
+         - conditionalWriter
+         - updates
+        """
+        self.send_updateRowsConditionally(conditionalWriter, updates)
+        return self.recv_updateRowsConditionally()
+
+    def send_updateRowsConditionally(self, conditionalWriter, updates):
+        self._oprot.writeMessageBegin('updateRowsConditionally', TMessageType.CALL, self._seqid)
+        args = updateRowsConditionally_args()
+        args.conditionalWriter = conditionalWriter
+        args.updates = updates
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_updateRowsConditionally(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = updateRowsConditionally_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, "updateRowsConditionally failed: unknown result")
+
+    def closeConditionalWriter(self, conditionalWriter):
+        """
+        Parameters:
+         - conditionalWriter
+        """
+        self.send_closeConditionalWriter(conditionalWriter)
+        self.recv_closeConditionalWriter()
+
+    def send_closeConditionalWriter(self, conditionalWriter):
+        self._oprot.writeMessageBegin('closeConditionalWriter', TMessageType.CALL, self._seqid)
+        args = closeConditionalWriter_args()
+        args.conditionalWriter = conditionalWriter
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_closeConditionalWriter(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = closeConditionalWriter_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        return
+
+    def getRowRange(self, row):
+        """
+        Parameters:
+         - row
+        """
+        self.send_getRowRange(row)
+        return self.recv_getRowRange()
+
+    def send_getRowRange(self, row):
+        self._oprot.writeMessageBegin('getRowRange', TMessageType.CALL, self._seqid)
+        args = getRowRange_args()
+        args.row = row
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getRowRange(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getRowRange_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.success is not None:
+            return result.success
+        raise TApplicationException(TApplicationException.MISSING_RESULT, "getRowRange failed: unknown result")
+
+    def getFollowing(self, key, part):
+        """
+        Parameters:
+         - key
+         - part
+        """
+        self.send_getFollowing(key, part)
+        return self.recv_getFollowing()
+
+    def send_getFollowing(self, key, part):
+        self._oprot.writeMessageBegin('getFollowing', TMessageType.CALL, self._seqid)
+        args = getFollowing_args()
+        args.key = key
+        args.part = part
+        args.write(self._oprot)
+        self._oprot.writeMessageEnd()
+        self._oprot.trans.flush()
+
+    def recv_getFollowing(self):
+        iprot = self._iprot
+        (fname, mtype, rseqid) = iprot.readMessageBegin()
+        if mtype == TMessageType.EXCEPTION:
+            x = TApplicationException()
+            x.read(iprot)
+            iprot.readMessageEnd()
+            raise x
+        result = getFollowing_result()
+        result.read(iprot)
+        iprot.readMessageEnd()
+        if result.success is not None:
+            return result.success
+        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):
+    def __init__(self, handler):
+        self._handler = handler
+        self._processMap = {}
+        self._processMap["login"] = Processor.process_login
+        self._processMap["addConstraint"] = Processor.process_addConstraint
+        self._processMap["addSplits"] = Processor.process_addSplits
+        self._processMap["attachIterator"] = Processor.process_attachIterator
+        self._processMap["checkIteratorConflicts"] = Processor.process_checkIteratorConflicts
+        self._processMap["clearLocatorCache"] = Processor.process_clearLocatorCache
+        self._processMap["cloneTable"] = Processor.process_cloneTable
+        self._processMap["compactTable"] = Processor.process_compactTable
+        self._processMap["cancelCompaction"] = Processor.process_cancelCompaction
+        self._processMap["createTable"] = Processor.process_createTable
+        self._processMap["deleteTable"] = Processor.process_deleteTable
+        self._processMap["deleteRows"] = Processor.process_deleteRows
+        self._processMap["exportTable"] = Processor.process_exportTable
+        self._processMap["flushTable"] = Processor.process_flushTable
+        self._processMap["getDiskUsage"] = Processor.process_getDiskUsage
+        self._processMap["getLocalityGroups"] = Processor.process_getLocalityGroups
+        self._processMap["getIteratorSetting"] = Processor.process_getIteratorSetting
+        self._processMap["getMaxRow"] = Processor.process_getMaxRow
+        self._processMap["getTableProperties"] = Processor.process_getTableProperties
+        self._processMap["importDirectory"] = Processor.process_importDirectory
+        self._processMap["importTable"] = Processor.process_importTable
+        self._processMap["listSplits"] = Processor.process_listSplits
+        self._processMap["listTables"] = Processor.process_listTables
+        self._processMap["listIterators"] = Processor.process_listIterators
+        self._processMap["listConstraints"] = Processor.process_listConstraints
+        self._processMap["mergeTablets"] = Processor.process_mergeTablets
+        self._processMap["offlineTable"] = Processor.process_offlineTable
+        self._processMap["onlineTable"] = Processor.process_onlineTable
+        self._processMap["removeConstraint"] = Processor.process_removeConstraint
+        self._processMap["removeIterator"] = Processor.process_removeIterator
+        self._processMap["removeTableProperty"] = Processor.process_removeTableProperty
+        self._processMap["renameTable"] = Processor.process_renameTable
+        self._processMap["setLocalityGroups"] = Processor.process_setLocalityGroups
+        self._processMap["setTableProperty"] = Processor.process_setTableProperty
+        self._processMap["splitRangeByTablets"] = Processor.process_splitRangeByTablets
+        self._processMap["tableExists"] = Processor.process_tableExists
+        self._processMap["tableIdMap"] = Processor.process_tableIdMap
+        self._processMap["testTableClassLoad"] = Processor.process_testTableClassLoad
+        self._processMap["pingTabletServer"] = Processor.process_pingTabletServer
+        self._processMap["getActiveScans"] = Processor.process_getActiveScans
+        self._processMap["getActiveCompactions"] = Processor.process_getActiveCompactions
+        self._processMap["getSiteConfiguration"] = Processor.process_getSiteConfiguration
+        self._processMap["getSystemConfiguration"] = Processor.process_getSystemConfiguration
+        self._processMap["getTabletServers"] = Processor.process_getTabletServers
+        self._processMap["removeProperty"] = Processor.process_removeProperty
+        self._processMap["setProperty"] = Processor.process_setProperty
+        self._processMap["testClassLoad"] = Processor.process_testClassLoad
+        self._processMap["authenticateUser"] = Processor.process_authenticateUser
+        self._processMap["changeUserAuthorizations"] = Processor.process_changeUserAuthorizations
+        self._processMap["changeLocalUserPassword"] = Processor.process_changeLocalUserPassword
+        self._processMap["createLocalUser"] = Processor.process_createLocalUser
+        self._processMap["dropLocalUser"] = Processor.process_dropLocalUser
+        self._processMap["getUserAuthorizations"] = Processor.process_getUserAuthorizations
+        self._processMap["grantSystemPermission"] = Processor.process_grantSystemPermission
+        self._processMap["grantTablePermission"] = Processor.process_grantTablePermission
+        self._processMap["hasSystemPermission"] = Processor.process_hasSystemPermission
+        self._processMap["hasTablePermission"] = Processor.process_hasTablePermission
+        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
+        self._processMap["nextEntry"] = Processor.process_nextEntry
+        self._processMap["nextK"] = Processor.process_nextK
+        self._processMap["closeScanner"] = Processor.process_closeScanner
+        self._processMap["updateAndFlush"] = Processor.process_updateAndFlush
+        self._processMap["createWriter"] = Processor.process_createWriter
+        self._processMap["update"] = Processor.process_update
+        self._processMap["flush"] = Processor.process_flush
+        self._processMap["closeWriter"] = Processor.process_closeWriter
+        self._processMap["updateRowConditionally"] = Processor.process_updateRowConditionally
+        self._processMap["createConditionalWriter"] = Processor.process_createConditionalWriter
+        self._processMap["updateRowsConditionally"] = Processor.process_updateRowsConditionally
+        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()
+        if name not in self._processMap:
+            iprot.skip(TType.STRUCT)
+            iprot.readMessageEnd()
+            x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))
+            oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
+            x.write(oprot)
+            oprot.writeMessageEnd()
+            oprot.trans.flush()
+            return
+        else:
+            self._processMap[name](self, seqid, iprot, oprot)
+        return True
+
+    def process_login(self, seqid, iprot, oprot):
+        args = login_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = login_result()
+        try:
+            result.success = self._handler.login(args.principal, args.loginProperties)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        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("login", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_addConstraint(self, seqid, iprot, oprot):
+        args = addConstraint_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = addConstraint_result()
+        try:
+            result.success = self._handler.addConstraint(args.login, args.tableName, 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 TableNotFoundException 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("addConstraint", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_addSplits(self, seqid, iprot, oprot):
+        args = addSplits_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = addSplits_result()
+        try:
+            self._handler.addSplits(args.login, args.tableName, args.splits)
+            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 TableNotFoundException 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("addSplits", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_attachIterator(self, seqid, iprot, oprot):
+        args = attachIterator_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = attachIterator_result()
+        try:
+            self._handler.attachIterator(args.login, args.tableName, args.setting, args.scopes)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except AccumuloSecurityException as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except AccumuloException as ouch2:
+            msg_type = TMessageType.REPLY
+            result.ouch2 = ouch2
+        except TableNotFoundException 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("attachIterator", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_checkIteratorConflicts(self, seqid, iprot, oprot):
+        args = checkIteratorConflicts_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = checkIteratorConflicts_result()
+        try:
+            self._handler.checkIteratorConflicts(args.login, args.tableName, args.setting, args.scopes)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except AccumuloSecurityException as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except AccumuloException as ouch2:
+            msg_type = TMessageType.REPLY
+            result.ouch2 = ouch2
+        except TableNotFoundException 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("checkIteratorConflicts", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_clearLocatorCache(self, seqid, iprot, oprot):
+        args = clearLocatorCache_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = clearLocatorCache_result()
+        try:
+            self._handler.clearLocatorCache(args.login, args.tableName)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except TableNotFoundException as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        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()
+
+    def process_cloneTable(self, seqid, iprot, oprot):
+        args = cloneTable_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = cloneTable_result()
+        try:
+            self._handler.cloneTable(args.login, args.tableName, args.newTableName, args.flush, args.propertiesToSet, args.propertiesToExclude)
+            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 TableNotFoundException as ouch3:
+            msg_type = TMessageType.REPLY
+            result.ouch3 = ouch3
+        except TableExistsException 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("cloneTable", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_compactTable(self, seqid, iprot, oprot):
+        args = compactTable_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = compactTable_result()
+        try:
+            self._handler.compactTable(args.login, args.tableName, args.startRow, args.endRow, args.iterators, args.flush, args.wait, args.compactionStrategy)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except AccumuloSecurityException as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except TableNotFoundException as ouch2:
+            msg_type = TMessageType.REPLY
+            result.ouch2 = ouch2
+        except AccumuloException 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("compactTable", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_cancelCompaction(self, seqid, iprot, oprot):
+        args = cancelCompaction_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = cancelCompaction_result()
+        try:
+            self._handler.cancelCompaction(args.login, args.tableName)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except AccumuloSecurityException as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except TableNotFoundException as ouch2:
+            msg_type = TMessageType.REPLY
+            result.ouch2 = ouch2
+        except AccumuloException 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("cancelCompaction", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_createTable(self, seqid, iprot, oprot):
+        args = createTable_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = createTable_result()
+        try:
+            self._handler.createTable(args.login, args.tableName, args.versioningIter, args.type)
+            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 TableExistsException 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("createTable", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_deleteTable(self, seqid, iprot, oprot):
+        args = deleteTable_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = deleteTable_result()
+        try:
+            self._handler.deleteTable(args.login, args.tableName)
+            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 TableNotFoundException 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("deleteTable", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_deleteRows(self, seqid, iprot, oprot):
+        args = deleteRows_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = deleteRows_result()
+        try:
+            self._handler.deleteRows(args.login, args.tableName, args.startRow, args.endRow)
+            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 TableNotFoundException 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("deleteRows", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_exportTable(self, seqid, iprot, oprot):
+        args = exportTable_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = exportTable_result()
+        try:
+            self._handler.exportTable(args.login, args.tableName, args.exportDir)
+            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 TableNotFoundException 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("exportTable", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_flushTable(self, seqid, iprot, oprot):
+        args = flushTable_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = flushTable_result()
+        try:
+            self._handler.flushTable(args.login, args.tableName, args.startRow, args.endRow, args.wait)
+            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 TableNotFoundException 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("flushTable", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getDiskUsage(self, seqid, iprot, oprot):
+        args = getDiskUsage_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getDiskUsage_result()
+        try:
+            result.success = self._handler.getDiskUsage(args.login, args.tables)
+            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 TableNotFoundException 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("getDiskUsage", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getLocalityGroups(self, seqid, iprot, oprot):
+        args = getLocalityGroups_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getLocalityGroups_result()
+        try:
+            result.success = self._handler.getLocalityGroups(args.login, args.tableName)
+            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 TableNotFoundException 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("getLocalityGroups", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getIteratorSetting(self, seqid, iprot, oprot):
+        args = getIteratorSetting_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getIteratorSetting_result()
+        try:
+            result.success = self._handler.getIteratorSetting(args.login, args.tableName, args.iteratorName, 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 TableNotFoundException 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("getIteratorSetting", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getMaxRow(self, seqid, iprot, oprot):
+        args = getMaxRow_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getMaxRow_result()
+        try:
+            result.success = self._handler.getMaxRow(args.login, args.tableName, args.auths, args.startRow, args.startInclusive, args.endRow, args.endInclusive)
+            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 TableNotFoundException 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("getMaxRow", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getTableProperties(self, seqid, iprot, oprot):
+        args = getTableProperties_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getTableProperties_result()
+        try:
+            result.success = self._handler.getTableProperties(args.login, args.tableName)
+            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 TableNotFoundException 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("getTableProperties", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_importDirectory(self, seqid, iprot, oprot):
+        args = importDirectory_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = importDirectory_result()
+        try:
+            self._handler.importDirectory(args.login, args.tableName, args.importDir, args.failureDir, args.setTime)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except TableNotFoundException as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except AccumuloException as ouch3:
+            msg_type = TMessageType.REPLY
+            result.ouch3 = ouch3
+        except AccumuloSecurityException 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("importDirectory", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_importTable(self, seqid, iprot, oprot):
+        args = importTable_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = importTable_result()
+        try:
+            self._handler.importTable(args.login, args.tableName, args.importDir)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except TableExistsException as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except AccumuloException as ouch2:
+            msg_type = TMessageType.REPLY
+            result.ouch2 = ouch2
+        except AccumuloSecurityException 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("importTable", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_listSplits(self, seqid, iprot, oprot):
+        args = listSplits_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = listSplits_result()
+        try:
+            result.success = self._handler.listSplits(args.login, args.tableName, args.maxSplits)
+            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 TableNotFoundException 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("listSplits", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_listTables(self, seqid, iprot, oprot):
+        args = listTables_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = listTables_result()
+        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()
+
+    def process_listIterators(self, seqid, iprot, oprot):
+        args = listIterators_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = listIterators_result()
+        try:
+            result.success = self._handler.listIterators(args.login, args.tableName)
+            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 TableNotFoundException 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("listIterators", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_listConstraints(self, seqid, iprot, oprot):
+        args = listConstraints_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = listConstraints_result()
+        try:
+            result.success = self._handler.listConstraints(args.login, args.tableName)
+            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 TableNotFoundException 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("listConstraints", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_mergeTablets(self, seqid, iprot, oprot):
+        args = mergeTablets_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = mergeTablets_result()
+        try:
+            self._handler.mergeTablets(args.login, args.tableName, args.startRow, args.endRow)
+            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 TableNotFoundException 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("mergeTablets", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_offlineTable(self, seqid, iprot, oprot):
+        args = offlineTable_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = offlineTable_result()
+        try:
+            self._handler.offlineTable(args.login, args.tableName, args.wait)
+            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 TableNotFoundException 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("offlineTable", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_onlineTable(self, seqid, iprot, oprot):
+        args = onlineTable_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = onlineTable_result()
+        try:
+            self._handler.onlineTable(args.login, args.tableName, args.wait)
+            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 TableNotFoundException 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("onlineTable", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_removeConstraint(self, seqid, iprot, oprot):
+        args = removeConstraint_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = removeConstraint_result()
+        try:
+            self._handler.removeConstraint(args.login, args.tableName, args.constraint)
+            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 TableNotFoundException 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("removeConstraint", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_removeIterator(self, seqid, iprot, oprot):
+        args = removeIterator_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = removeIterator_result()
+        try:
+            self._handler.removeIterator(args.login, args.tableName, args.iterName, 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 TableNotFoundException 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("removeIterator", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_removeTableProperty(self, seqid, iprot, oprot):
+        args = removeTableProperty_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = removeTableProperty_result()
+        try:
+            self._handler.removeTableProperty(args.login, args.tableName, 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 TableNotFoundException 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("removeTableProperty", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_renameTable(self, seqid, iprot, oprot):
+        args = renameTable_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = renameTable_result()
+        try:
+            self._handler.renameTable(args.login, args.oldTableName, args.newTableName)
+            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 TableNotFoundException as ouch3:
+            msg_type = TMessageType.REPLY
+            result.ouch3 = ouch3
+        except TableExistsException 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("renameTable", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_setLocalityGroups(self, seqid, iprot, oprot):
+        args = setLocalityGroups_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = setLocalityGroups_result()
+        try:
+            self._handler.setLocalityGroups(args.login, args.tableName, args.groups)
+            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 TableNotFoundException 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("setLocalityGroups", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_setTableProperty(self, seqid, iprot, oprot):
+        args = setTableProperty_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = setTableProperty_result()
+        try:
+            self._handler.setTableProperty(args.login, args.tableName, 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 TableNotFoundException 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("setTableProperty", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_splitRangeByTablets(self, seqid, iprot, oprot):
+        args = splitRangeByTablets_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = splitRangeByTablets_result()
+        try:
+            result.success = self._handler.splitRangeByTablets(args.login, args.tableName, args.range, args.maxSplits)
+            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 TableNotFoundException 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("splitRangeByTablets", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_tableExists(self, seqid, iprot, oprot):
+        args = tableExists_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = tableExists_result()
+        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()
+
+    def process_tableIdMap(self, seqid, iprot, oprot):
+        args = tableIdMap_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = tableIdMap_result()
+        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()
+
+    def process_testTableClassLoad(self, seqid, iprot, oprot):
+        args = testTableClassLoad_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = testTableClassLoad_result()
+        try:
+            result.success = self._handler.testTableClassLoad(args.login, args.tableName, 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 TableNotFoundException 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("testTableClassLoad", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_pingTabletServer(self, seqid, iprot, oprot):
+        args = pingTabletServer_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = pingTabletServer_result()
+        try:
+            self._handler.pingTabletServer(args.login, args.tserver)
+            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("pingTabletServer", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getActiveScans(self, seqid, iprot, oprot):
+        args = getActiveScans_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getActiveScans_result()
+        try:
+            result.success = self._handler.getActiveScans(args.login, args.tserver)
+            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("getActiveScans", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getActiveCompactions(self, seqid, iprot, oprot):
+        args = getActiveCompactions_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getActiveCompactions_result()
+        try:
+            result.success = self._handler.getActiveCompactions(args.login, args.tserver)
+            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("getActiveCompactions", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getSiteConfiguration(self, seqid, iprot, oprot):
+        args = getSiteConfiguration_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getSiteConfiguration_result()
+        try:
+            result.success = self._handler.getSiteConfiguration(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("getSiteConfiguration", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getSystemConfiguration(self, seqid, iprot, oprot):
+        args = getSystemConfiguration_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getSystemConfiguration_result()
+        try:
+            result.success = self._handler.getSystemConfiguration(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("getSystemConfiguration", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getTabletServers(self, seqid, iprot, oprot):
+        args = getTabletServers_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getTabletServers_result()
+        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()
+
+    def process_removeProperty(self, seqid, iprot, oprot):
+        args = removeProperty_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = removeProperty_result()
+        try:
+            self._handler.removeProperty(args.login, 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 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()
+
+    def process_setProperty(self, seqid, iprot, oprot):
+        args = setProperty_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = setProperty_result()
+        try:
+            self._handler.setProperty(args.login, 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 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()
+
+    def process_testClassLoad(self, seqid, iprot, oprot):
+        args = testClassLoad_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = testClassLoad_result()
+        try:
+            result.success = self._handler.testClassLoad(args.login, 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 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()
+
+    def process_authenticateUser(self, seqid, iprot, oprot):
+        args = authenticateUser_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = authenticateUser_result()
+        try:
+            result.success = self._handler.authenticateUser(args.login, args.user, args.properties)
+            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("authenticateUser", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_changeUserAuthorizations(self, seqid, iprot, oprot):
+        args = changeUserAuthorizations_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = changeUserAuthorizations_result()
+        try:
+            self._handler.changeUserAuthorizations(args.login, args.user, args.authorizations)
+            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("changeUserAuthorizations", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_changeLocalUserPassword(self, seqid, iprot, oprot):
+        args = changeLocalUserPassword_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = changeLocalUserPassword_result()
+        try:
+            self._handler.changeLocalUserPassword(args.login, args.user, args.password)
+            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("changeLocalUserPassword", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_createLocalUser(self, seqid, iprot, oprot):
+        args = createLocalUser_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = createLocalUser_result()
+        try:
+            self._handler.createLocalUser(args.login, args.user, args.password)
+            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("createLocalUser", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_dropLocalUser(self, seqid, iprot, oprot):
+        args = dropLocalUser_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = dropLocalUser_result()
+        try:
+            self._handler.dropLocalUser(args.login, args.user)
+            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("dropLocalUser", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_getUserAuthorizations(self, seqid, iprot, oprot):
+        args = getUserAuthorizations_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getUserAuthorizations_result()
+        try:
+            result.success = self._handler.getUserAuthorizations(args.login, args.user)
+            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("getUserAuthorizations", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_grantSystemPermission(self, seqid, iprot, oprot):
+        args = grantSystemPermission_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = grantSystemPermission_result()
+        try:
+            self._handler.grantSystemPermission(args.login, args.user, 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("grantSystemPermission", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_grantTablePermission(self, seqid, iprot, oprot):
+        args = grantTablePermission_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = grantTablePermission_result()
+        try:
+            self._handler.grantTablePermission(args.login, args.user, args.table, 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 TableNotFoundException 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("grantTablePermission", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_hasSystemPermission(self, seqid, iprot, oprot):
+        args = hasSystemPermission_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = hasSystemPermission_result()
+        try:
+            result.success = self._handler.hasSystemPermission(args.login, args.user, 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("hasSystemPermission", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_hasTablePermission(self, seqid, iprot, oprot):
+        args = hasTablePermission_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = hasTablePermission_result()
+        try:
+            result.success = self._handler.hasTablePermission(args.login, args.user, args.table, 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 TableNotFoundException 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("hasTablePermission", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_listLocalUsers(self, seqid, iprot, oprot):
+        args = listLocalUsers_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = listLocalUsers_result()
+        try:
+            result.success = self._handler.listLocalUsers(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 TableNotFoundException 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("listLocalUsers", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_revokeSystemPermission(self, seqid, iprot, oprot):
+        args = revokeSystemPermission_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = revokeSystemPermission_result()
+        try:
+            self._handler.revokeSystemPermission(args.login, args.user, 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("revokeSystemPermission", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_revokeTablePermission(self, seqid, iprot, oprot):
+        args = revokeTablePermission_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = revokeTablePermission_result()
+        try:
+            self._handler.revokeTablePermission(args.login, args.user, args.table, 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 TableNotFoundException 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("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()
+
+    def process_createBatchScanner(self, seqid, iprot, oprot):
+        args = createBatchScanner_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = createBatchScanner_result()
+        try:
+            result.success = self._handler.createBatchScanner(args.login, args.tableName, args.options)
+            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 TableNotFoundException 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("createBatchScanner", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_createScanner(self, seqid, iprot, oprot):
+        args = createScanner_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = createScanner_result()
+        try:
+            result.success = self._handler.createScanner(args.login, args.tableName, args.options)
+            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 TableNotFoundException 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("createScanner", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_hasNext(self, seqid, iprot, oprot):
+        args = hasNext_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = hasNext_result()
+        try:
+            result.success = self._handler.hasNext(args.scanner)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except UnknownScanner as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        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()
+
+    def process_nextEntry(self, seqid, iprot, oprot):
+        args = nextEntry_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = nextEntry_result()
+        try:
+            result.success = self._handler.nextEntry(args.scanner)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except NoMoreEntriesException as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except UnknownScanner as ouch2:
+            msg_type = TMessageType.REPLY
+            result.ouch2 = ouch2
+        except AccumuloSecurityException 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("nextEntry", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_nextK(self, seqid, iprot, oprot):
+        args = nextK_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = nextK_result()
+        try:
+            result.success = self._handler.nextK(args.scanner, args.k)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except NoMoreEntriesException as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except UnknownScanner as ouch2:
+            msg_type = TMessageType.REPLY
+            result.ouch2 = ouch2
+        except AccumuloSecurityException 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("nextK", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_closeScanner(self, seqid, iprot, oprot):
+        args = closeScanner_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = closeScanner_result()
+        try:
+            self._handler.closeScanner(args.scanner)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except UnknownScanner as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        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()
+
+    def process_updateAndFlush(self, seqid, iprot, oprot):
+        args = updateAndFlush_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = updateAndFlush_result()
+        try:
+            self._handler.updateAndFlush(args.login, args.tableName, args.cells)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except AccumuloException as outch1:
+            msg_type = TMessageType.REPLY
+            result.outch1 = outch1
+        except AccumuloSecurityException as ouch2:
+            msg_type = TMessageType.REPLY
+            result.ouch2 = ouch2
+        except TableNotFoundException as ouch3:
+            msg_type = TMessageType.REPLY
+            result.ouch3 = ouch3
+        except MutationsRejectedException 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("updateAndFlush", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_createWriter(self, seqid, iprot, oprot):
+        args = createWriter_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = createWriter_result()
+        try:
+            result.success = self._handler.createWriter(args.login, args.tableName, args.opts)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except AccumuloException as outch1:
+            msg_type = TMessageType.REPLY
+            result.outch1 = outch1
+        except AccumuloSecurityException as ouch2:
+            msg_type = TMessageType.REPLY
+            result.ouch2 = ouch2
+        except TableNotFoundException 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("createWriter", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_update(self, seqid, iprot, oprot):
+        args = update_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        try:
+            self._handler.update(args.writer, args.cells)
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            pass
+
+    def process_flush(self, seqid, iprot, oprot):
+        args = flush_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = flush_result()
+        try:
+            self._handler.flush(args.writer)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except UnknownWriter as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except MutationsRejectedException 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("flush", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_closeWriter(self, seqid, iprot, oprot):
+        args = closeWriter_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = closeWriter_result()
+        try:
+            self._handler.closeWriter(args.writer)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except UnknownWriter as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except MutationsRejectedException 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("closeWriter", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_updateRowConditionally(self, seqid, iprot, oprot):
+        args = updateRowConditionally_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = updateRowConditionally_result()
+        try:
+            result.success = self._handler.updateRowConditionally(args.login, args.tableName, args.row, args.updates)
+            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 TableNotFoundException 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("updateRowConditionally", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_createConditionalWriter(self, seqid, iprot, oprot):
+        args = createConditionalWriter_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = createConditionalWriter_result()
+        try:
+            result.success = self._handler.createConditionalWriter(args.login, args.tableName, args.options)
+            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 TableNotFoundException 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("createConditionalWriter", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_updateRowsConditionally(self, seqid, iprot, oprot):
+        args = updateRowsConditionally_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = updateRowsConditionally_result()
+        try:
+            result.success = self._handler.updateRowsConditionally(args.conditionalWriter, args.updates)
+            msg_type = TMessageType.REPLY
+        except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
+            raise
+        except UnknownWriter as ouch1:
+            msg_type = TMessageType.REPLY
+            result.ouch1 = ouch1
+        except AccumuloException as ouch2:
+            msg_type = TMessageType.REPLY
+            result.ouch2 = ouch2
+        except AccumuloSecurityException 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("updateRowsConditionally", msg_type, seqid)
+        result.write(oprot)
+        oprot.writeMessageEnd()
+        oprot.trans.flush()
+
+    def process_closeConditionalWriter(self, seqid, iprot, oprot):
+        args = closeConditionalWriter_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = closeConditionalWriter_result()
+        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()
+
+    def process_getRowRange(self, seqid, iprot, oprot):
+        args = getRowRange_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getRowRange_result()
+        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()
+
+    def process_getFollowing(self, seqid, iprot, oprot):
+        args = getFollowing_args()
+        args.read(iprot)
+        iprot.readMessageEnd()
+        result = getFollowing_result()
+        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()
+
+# HELPER FUNCTIONS AND STRUCTURES
+
+
+class login_args(object):
     """
-    Parameters:
+    Attributes:
      - principal
      - loginProperties
     """
-    self.send_login(principal, loginProperties)
-    return self.recv_login()
 
-  def send_login(self, principal, loginProperties):
-    self._oprot.writeMessageBegin('login', TMessageType.CALL, self._seqid)
-    args = login_args()
-    args.principal = principal
-    args.loginProperties = loginProperties
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'principal', 'UTF8', None, ),  # 1
+        (2, TType.MAP, 'loginProperties', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), None, ),  # 2
+    )
 
-  def recv_login(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = login_result()
-    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")
+    def __init__(self, principal=None, loginProperties=None,):
+        self.principal = principal
+        self.loginProperties = loginProperties
 
-  def addConstraint(self, login, tableName, constraintClassName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.principal = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.MAP:
+                    self.loginProperties = {}
+                    (_ktype145, _vtype146, _size144) = iprot.readMapBegin()
+                    for _i148 in range(_size144):
+                        _key149 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val150 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.loginProperties[_key149] = _val150
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('login_args')
+        if self.principal is not None:
+            oprot.writeFieldBegin('principal', TType.STRING, 1)
+            oprot.writeString(self.principal.encode('utf-8') if sys.version_info[0] == 2 else self.principal)
+            oprot.writeFieldEnd()
+        if self.loginProperties is not None:
+            oprot.writeFieldBegin('loginProperties', TType.MAP, 2)
+            oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.loginProperties))
+            for kiter151, viter152 in self.loginProperties.items():
+                oprot.writeString(kiter151.encode('utf-8') if sys.version_info[0] == 2 else kiter151)
+                oprot.writeString(viter152.encode('utf-8') if sys.version_info[0] == 2 else viter152)
+            oprot.writeMapEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 login_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch2
+    """
+
+    thrift_spec = (
+        (0, TType.STRING, 'success', 'BINARY', None, ),  # 0
+        (1, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ),  # 1
+    )
+
+    def __init__(self, success=None, ouch2=None,):
+        self.success = success
+        self.ouch2 = ouch2
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 1:
+                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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('login_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.STRING, 0)
+            oprot.writeBinary(self.success)
+            oprot.writeFieldEnd()
+        if self.ouch2 is not None:
+            oprot.writeFieldBegin('ouch2', TType.STRUCT, 1)
+            self.ouch2.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 addConstraint_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - constraintClassName
     """
-    self.send_addConstraint(login, tableName, constraintClassName)
-    return self.recv_addConstraint()
 
-  def send_addConstraint(self, login, tableName, constraintClassName):
-    self._oprot.writeMessageBegin('addConstraint', TMessageType.CALL, self._seqid)
-    args = addConstraint_args()
-    args.login = login
-    args.tableName = tableName
-    args.constraintClassName = constraintClassName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'constraintClassName', 'UTF8', None, ),  # 3
+    )
 
-  def recv_addConstraint(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = addConstraint_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, "addConstraint failed: unknown result")
+    def __init__(self, login=None, tableName=None, constraintClassName=None,):
+        self.login = login
+        self.tableName = tableName
+        self.constraintClassName = constraintClassName
 
-  def addSplits(self, login, tableName, splits):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.constraintClassName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('addConstraint_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.constraintClassName is not None:
+            oprot.writeFieldBegin('constraintClassName', TType.STRING, 3)
+            oprot.writeString(self.constraintClassName.encode('utf-8') if sys.version_info[0] == 2 else self.constraintClassName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 addConstraint_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('addConstraint_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 addSplits_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - splits
     """
-    self.send_addSplits(login, tableName, splits)
-    self.recv_addSplits()
 
-  def send_addSplits(self, login, tableName, splits):
-    self._oprot.writeMessageBegin('addSplits', TMessageType.CALL, self._seqid)
-    args = addSplits_args()
-    args.login = login
-    args.tableName = tableName
-    args.splits = splits
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.SET, 'splits', (TType.STRING, 'BINARY', False), None, ),  # 3
+    )
 
-  def recv_addSplits(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = addSplits_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 __init__(self, login=None, tableName=None, splits=None,):
+        self.login = login
+        self.tableName = tableName
+        self.splits = splits
 
-  def attachIterator(self, login, tableName, setting, scopes):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.SET:
+                    self.splits = set()
+                    (_etype156, _size153) = iprot.readSetBegin()
+                    for _i157 in range(_size153):
+                        _elem158 = iprot.readBinary()
+                        self.splits.add(_elem158)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('addSplits_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.splits is not None:
+            oprot.writeFieldBegin('splits', TType.SET, 3)
+            oprot.writeSetBegin(TType.STRING, len(self.splits))
+            for iter159 in self.splits:
+                oprot.writeBinary(iter159)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 addSplits_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('addSplits_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 attachIterator_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - setting
      - scopes
     """
-    self.send_attachIterator(login, tableName, setting, scopes)
-    self.recv_attachIterator()
 
-  def send_attachIterator(self, login, tableName, setting, scopes):
-    self._oprot.writeMessageBegin('attachIterator', TMessageType.CALL, self._seqid)
-    args = attachIterator_args()
-    args.login = login
-    args.tableName = tableName
-    args.setting = setting
-    args.scopes = scopes
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRUCT, 'setting', (IteratorSetting, IteratorSetting.thrift_spec), None, ),  # 3
+        (4, TType.SET, 'scopes', (TType.I32, None, False), None, ),  # 4
+    )
 
-  def recv_attachIterator(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = attachIterator_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 __init__(self, login=None, tableName=None, setting=None, scopes=None,):
+        self.login = login
+        self.tableName = tableName
+        self.setting = setting
+        self.scopes = scopes
 
-  def checkIteratorConflicts(self, login, tableName, setting, scopes):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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()
+                    (_etype163, _size160) = iprot.readSetBegin()
+                    for _i164 in range(_size160):
+                        _elem165 = iprot.readI32()
+                        self.scopes.add(_elem165)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('attachIterator_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            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 iter166 in self.scopes:
+                oprot.writeI32(iter166)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 attachIterator_result(object):
     """
-    Parameters:
+    Attributes:
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'ouch1', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (AccumuloException, AccumuloException.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch3', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = AccumuloSecurityException()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch2 = AccumuloException()
+                    self.ouch2.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('attachIterator_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 checkIteratorConflicts_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - setting
      - scopes
     """
-    self.send_checkIteratorConflicts(login, tableName, setting, scopes)
-    self.recv_checkIteratorConflicts()
 
-  def send_checkIteratorConflicts(self, login, tableName, setting, scopes):
-    self._oprot.writeMessageBegin('checkIteratorConflicts', TMessageType.CALL, self._seqid)
-    args = checkIteratorConflicts_args()
-    args.login = login
-    args.tableName = tableName
-    args.setting = setting
-    args.scopes = scopes
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRUCT, 'setting', (IteratorSetting, IteratorSetting.thrift_spec), None, ),  # 3
+        (4, TType.SET, 'scopes', (TType.I32, None, False), None, ),  # 4
+    )
 
-  def recv_checkIteratorConflicts(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = checkIteratorConflicts_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 __init__(self, login=None, tableName=None, setting=None, scopes=None,):
+        self.login = login
+        self.tableName = tableName
+        self.setting = setting
+        self.scopes = scopes
 
-  def clearLocatorCache(self, login, tableName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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()
+                    (_etype170, _size167) = iprot.readSetBegin()
+                    for _i171 in range(_size167):
+                        _elem172 = iprot.readI32()
+                        self.scopes.add(_elem172)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('checkIteratorConflicts_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            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 iter173 in self.scopes:
+                oprot.writeI32(iter173)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 checkIteratorConflicts_result(object):
     """
-    Parameters:
+    Attributes:
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'ouch1', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (AccumuloException, AccumuloException.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch3', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = AccumuloSecurityException()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch2 = AccumuloException()
+                    self.ouch2.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('checkIteratorConflicts_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 clearLocatorCache_args(object):
+    """
+    Attributes:
      - login
      - tableName
     """
-    self.send_clearLocatorCache(login, tableName)
-    self.recv_clearLocatorCache()
 
-  def send_clearLocatorCache(self, login, tableName):
-    self._oprot.writeMessageBegin('clearLocatorCache', TMessageType.CALL, self._seqid)
-    args = clearLocatorCache_args()
-    args.login = login
-    args.tableName = tableName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+    )
 
-  def recv_clearLocatorCache(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = clearLocatorCache_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.ouch1 is not None:
-      raise result.ouch1
-    return
+    def __init__(self, login=None, tableName=None,):
+        self.login = login
+        self.tableName = tableName
 
-  def cloneTable(self, login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('clearLocatorCache_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 clearLocatorCache_result(object):
     """
-    Parameters:
+    Attributes:
+     - ouch1
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'ouch1', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ),  # 1
+    )
+
+    def __init__(self, ouch1=None,):
+        self.ouch1 = ouch1
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('clearLocatorCache_result')
+        if self.ouch1 is not None:
+            oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+            self.ouch1.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 cloneTable_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - newTableName
@@ -1152,46 +8509,237 @@
      - propertiesToSet
      - propertiesToExclude
     """
-    self.send_cloneTable(login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude)
-    self.recv_cloneTable()
 
-  def send_cloneTable(self, login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude):
-    self._oprot.writeMessageBegin('cloneTable', TMessageType.CALL, self._seqid)
-    args = cloneTable_args()
-    args.login = login
-    args.tableName = tableName
-    args.newTableName = newTableName
-    args.flush = flush
-    args.propertiesToSet = propertiesToSet
-    args.propertiesToExclude = propertiesToExclude
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'newTableName', 'UTF8', None, ),  # 3
+        (4, TType.BOOL, 'flush', None, None, ),  # 4
+        (5, TType.MAP, 'propertiesToSet', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), None, ),  # 5
+        (6, TType.SET, 'propertiesToExclude', (TType.STRING, 'UTF8', False), None, ),  # 6
+    )
 
-  def recv_cloneTable(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = cloneTable_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 __init__(self, login=None, tableName=None, newTableName=None, flush=None, propertiesToSet=None, propertiesToExclude=None,):
+        self.login = login
+        self.tableName = tableName
+        self.newTableName = newTableName
+        self.flush = flush
+        self.propertiesToSet = propertiesToSet
+        self.propertiesToExclude = propertiesToExclude
 
-  def compactTable(self, login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.newTableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.BOOL:
+                    self.flush = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.MAP:
+                    self.propertiesToSet = {}
+                    (_ktype175, _vtype176, _size174) = iprot.readMapBegin()
+                    for _i178 in range(_size174):
+                        _key179 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val180 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.propertiesToSet[_key179] = _val180
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 6:
+                if ftype == TType.SET:
+                    self.propertiesToExclude = set()
+                    (_etype184, _size181) = iprot.readSetBegin()
+                    for _i185 in range(_size181):
+                        _elem186 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.propertiesToExclude.add(_elem186)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('cloneTable_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.newTableName is not None:
+            oprot.writeFieldBegin('newTableName', TType.STRING, 3)
+            oprot.writeString(self.newTableName.encode('utf-8') if sys.version_info[0] == 2 else self.newTableName)
+            oprot.writeFieldEnd()
+        if self.flush is not None:
+            oprot.writeFieldBegin('flush', TType.BOOL, 4)
+            oprot.writeBool(self.flush)
+            oprot.writeFieldEnd()
+        if self.propertiesToSet is not None:
+            oprot.writeFieldBegin('propertiesToSet', TType.MAP, 5)
+            oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.propertiesToSet))
+            for kiter187, viter188 in self.propertiesToSet.items():
+                oprot.writeString(kiter187.encode('utf-8') if sys.version_info[0] == 2 else kiter187)
+                oprot.writeString(viter188.encode('utf-8') if sys.version_info[0] == 2 else viter188)
+            oprot.writeMapEnd()
+            oprot.writeFieldEnd()
+        if self.propertiesToExclude is not None:
+            oprot.writeFieldBegin('propertiesToExclude', TType.SET, 6)
+            oprot.writeSetBegin(TType.STRING, len(self.propertiesToExclude))
+            for iter189 in self.propertiesToExclude:
+                oprot.writeString(iter189.encode('utf-8') if sys.version_info[0] == 2 else iter189)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 cloneTable_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ),  # 3
+        (4, TType.STRUCT, 'ouch4', (TableExistsException, TableExistsException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRUCT:
+                    self.ouch4 = TableExistsException()
+                    self.ouch4.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('cloneTable_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 compactTable_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - startRow
@@ -1201,405 +8749,1858 @@
      - wait
      - compactionStrategy
     """
-    self.send_compactTable(login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy)
-    self.recv_compactTable()
 
-  def send_compactTable(self, login, tableName, startRow, endRow, iterators, flush, wait, compactionStrategy):
-    self._oprot.writeMessageBegin('compactTable', TMessageType.CALL, self._seqid)
-    args = compactTable_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(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'startRow', 'BINARY', None, ),  # 3
+        (4, TType.STRING, 'endRow', 'BINARY', None, ),  # 4
+        (5, TType.LIST, 'iterators', (TType.STRUCT, (IteratorSetting, IteratorSetting.thrift_spec), False), None, ),  # 5
+        (6, TType.BOOL, 'flush', None, None, ),  # 6
+        (7, TType.BOOL, 'wait', None, None, ),  # 7
+        (8, TType.STRUCT, 'compactionStrategy', (CompactionStrategyConfig, CompactionStrategyConfig.thrift_spec), None, ),  # 8
+    )
 
-  def recv_compactTable(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = compactTable_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 __init__(self, login=None, tableName=None, startRow=None, endRow=None, iterators=None, flush=None, wait=None, compactionStrategy=None,):
+        self.login = login
+        self.tableName = tableName
+        self.startRow = startRow
+        self.endRow = endRow
+        self.iterators = iterators
+        self.flush = flush
+        self.wait = wait
+        self.compactionStrategy = compactionStrategy
 
-  def cancelCompaction(self, login, tableName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.startRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.endRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.LIST:
+                    self.iterators = []
+                    (_etype193, _size190) = iprot.readListBegin()
+                    for _i194 in range(_size190):
+                        _elem195 = IteratorSetting()
+                        _elem195.read(iprot)
+                        self.iterators.append(_elem195)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 6:
+                if ftype == TType.BOOL:
+                    self.flush = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 7:
+                if ftype == TType.BOOL:
+                    self.wait = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 8:
+                if ftype == TType.STRUCT:
+                    self.compactionStrategy = CompactionStrategyConfig()
+                    self.compactionStrategy.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('compactTable_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.startRow is not None:
+            oprot.writeFieldBegin('startRow', TType.STRING, 3)
+            oprot.writeBinary(self.startRow)
+            oprot.writeFieldEnd()
+        if self.endRow is not None:
+            oprot.writeFieldBegin('endRow', TType.STRING, 4)
+            oprot.writeBinary(self.endRow)
+            oprot.writeFieldEnd()
+        if self.iterators is not None:
+            oprot.writeFieldBegin('iterators', TType.LIST, 5)
+            oprot.writeListBegin(TType.STRUCT, len(self.iterators))
+            for iter196 in self.iterators:
+                iter196.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.flush is not None:
+            oprot.writeFieldBegin('flush', TType.BOOL, 6)
+            oprot.writeBool(self.flush)
+            oprot.writeFieldEnd()
+        if self.wait is not None:
+            oprot.writeFieldBegin('wait', TType.BOOL, 7)
+            oprot.writeBool(self.wait)
+            oprot.writeFieldEnd()
+        if self.compactionStrategy is not None:
+            oprot.writeFieldBegin('compactionStrategy', TType.STRUCT, 8)
+            self.compactionStrategy.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 compactTable_result(object):
     """
-    Parameters:
+    Attributes:
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'ouch1', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch3', (AccumuloException, AccumuloException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = AccumuloSecurityException()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch2 = TableNotFoundException()
+                    self.ouch2.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = AccumuloException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('compactTable_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 cancelCompaction_args(object):
+    """
+    Attributes:
      - login
      - tableName
     """
-    self.send_cancelCompaction(login, tableName)
-    self.recv_cancelCompaction()
 
-  def send_cancelCompaction(self, login, tableName):
-    self._oprot.writeMessageBegin('cancelCompaction', TMessageType.CALL, self._seqid)
-    args = cancelCompaction_args()
-    args.login = login
-    args.tableName = tableName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+    )
 
-  def recv_cancelCompaction(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = cancelCompaction_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 __init__(self, login=None, tableName=None,):
+        self.login = login
+        self.tableName = tableName
 
-  def createTable(self, login, tableName, versioningIter, type):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('cancelCompaction_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 cancelCompaction_result(object):
     """
-    Parameters:
+    Attributes:
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'ouch1', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch3', (AccumuloException, AccumuloException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = AccumuloSecurityException()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch2 = TableNotFoundException()
+                    self.ouch2.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = AccumuloException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('cancelCompaction_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createTable_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - versioningIter
      - type
     """
-    self.send_createTable(login, tableName, versioningIter, type)
-    self.recv_createTable()
 
-  def send_createTable(self, login, tableName, versioningIter, type):
-    self._oprot.writeMessageBegin('createTable', TMessageType.CALL, self._seqid)
-    args = createTable_args()
-    args.login = login
-    args.tableName = tableName
-    args.versioningIter = versioningIter
-    args.type = type
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.BOOL, 'versioningIter', None, None, ),  # 3
+        (4, TType.I32, 'type', None, None, ),  # 4
+    )
 
-  def recv_createTable(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = createTable_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 __init__(self, login=None, tableName=None, versioningIter=None, type=None,):
+        self.login = login
+        self.tableName = tableName
+        self.versioningIter = versioningIter
+        self.type = type
 
-  def deleteTable(self, login, tableName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.BOOL:
+                    self.versioningIter = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.I32:
+                    self.type = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createTable_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.versioningIter is not None:
+            oprot.writeFieldBegin('versioningIter', TType.BOOL, 3)
+            oprot.writeBool(self.versioningIter)
+            oprot.writeFieldEnd()
+        if self.type is not None:
+            oprot.writeFieldBegin('type', TType.I32, 4)
+            oprot.writeI32(self.type)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createTable_result(object):
     """
-    Parameters:
+    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', (TableExistsException, TableExistsException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableExistsException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createTable_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 deleteTable_args(object):
+    """
+    Attributes:
      - login
      - tableName
     """
-    self.send_deleteTable(login, tableName)
-    self.recv_deleteTable()
 
-  def send_deleteTable(self, login, tableName):
-    self._oprot.writeMessageBegin('deleteTable', TMessageType.CALL, self._seqid)
-    args = deleteTable_args()
-    args.login = login
-    args.tableName = tableName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+    )
 
-  def recv_deleteTable(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = deleteTable_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 __init__(self, login=None, tableName=None,):
+        self.login = login
+        self.tableName = tableName
 
-  def deleteRows(self, login, tableName, startRow, endRow):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('deleteTable_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 deleteTable_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('deleteTable_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 deleteRows_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - startRow
      - endRow
     """
-    self.send_deleteRows(login, tableName, startRow, endRow)
-    self.recv_deleteRows()
 
-  def send_deleteRows(self, login, tableName, startRow, endRow):
-    self._oprot.writeMessageBegin('deleteRows', TMessageType.CALL, self._seqid)
-    args = deleteRows_args()
-    args.login = login
-    args.tableName = tableName
-    args.startRow = startRow
-    args.endRow = endRow
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'startRow', 'BINARY', None, ),  # 3
+        (4, TType.STRING, 'endRow', 'BINARY', None, ),  # 4
+    )
 
-  def recv_deleteRows(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = deleteRows_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 __init__(self, login=None, tableName=None, startRow=None, endRow=None,):
+        self.login = login
+        self.tableName = tableName
+        self.startRow = startRow
+        self.endRow = endRow
 
-  def exportTable(self, login, tableName, exportDir):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.startRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.endRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('deleteRows_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.startRow is not None:
+            oprot.writeFieldBegin('startRow', TType.STRING, 3)
+            oprot.writeBinary(self.startRow)
+            oprot.writeFieldEnd()
+        if self.endRow is not None:
+            oprot.writeFieldBegin('endRow', TType.STRING, 4)
+            oprot.writeBinary(self.endRow)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 deleteRows_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('deleteRows_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 exportTable_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - exportDir
     """
-    self.send_exportTable(login, tableName, exportDir)
-    self.recv_exportTable()
 
-  def send_exportTable(self, login, tableName, exportDir):
-    self._oprot.writeMessageBegin('exportTable', TMessageType.CALL, self._seqid)
-    args = exportTable_args()
-    args.login = login
-    args.tableName = tableName
-    args.exportDir = exportDir
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'exportDir', 'UTF8', None, ),  # 3
+    )
 
-  def recv_exportTable(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = exportTable_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 __init__(self, login=None, tableName=None, exportDir=None,):
+        self.login = login
+        self.tableName = tableName
+        self.exportDir = exportDir
 
-  def flushTable(self, login, tableName, startRow, endRow, wait):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.exportDir = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('exportTable_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.exportDir is not None:
+            oprot.writeFieldBegin('exportDir', TType.STRING, 3)
+            oprot.writeString(self.exportDir.encode('utf-8') if sys.version_info[0] == 2 else self.exportDir)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 exportTable_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('exportTable_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 flushTable_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - startRow
      - endRow
      - wait
     """
-    self.send_flushTable(login, tableName, startRow, endRow, wait)
-    self.recv_flushTable()
 
-  def send_flushTable(self, login, tableName, startRow, endRow, wait):
-    self._oprot.writeMessageBegin('flushTable', TMessageType.CALL, self._seqid)
-    args = flushTable_args()
-    args.login = login
-    args.tableName = tableName
-    args.startRow = startRow
-    args.endRow = endRow
-    args.wait = wait
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'startRow', 'BINARY', None, ),  # 3
+        (4, TType.STRING, 'endRow', 'BINARY', None, ),  # 4
+        (5, TType.BOOL, 'wait', None, None, ),  # 5
+    )
 
-  def recv_flushTable(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = flushTable_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 __init__(self, login=None, tableName=None, startRow=None, endRow=None, wait=None,):
+        self.login = login
+        self.tableName = tableName
+        self.startRow = startRow
+        self.endRow = endRow
+        self.wait = wait
 
-  def getDiskUsage(self, login, tables):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.startRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.endRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.BOOL:
+                    self.wait = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('flushTable_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.startRow is not None:
+            oprot.writeFieldBegin('startRow', TType.STRING, 3)
+            oprot.writeBinary(self.startRow)
+            oprot.writeFieldEnd()
+        if self.endRow is not None:
+            oprot.writeFieldBegin('endRow', TType.STRING, 4)
+            oprot.writeBinary(self.endRow)
+            oprot.writeFieldEnd()
+        if self.wait is not None:
+            oprot.writeFieldBegin('wait', TType.BOOL, 5)
+            oprot.writeBool(self.wait)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 flushTable_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('flushTable_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getDiskUsage_args(object):
+    """
+    Attributes:
      - login
      - tables
     """
-    self.send_getDiskUsage(login, tables)
-    return self.recv_getDiskUsage()
 
-  def send_getDiskUsage(self, login, tables):
-    self._oprot.writeMessageBegin('getDiskUsage', TMessageType.CALL, self._seqid)
-    args = getDiskUsage_args()
-    args.login = login
-    args.tables = tables
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.SET, 'tables', (TType.STRING, 'UTF8', False), None, ),  # 2
+    )
 
-  def recv_getDiskUsage(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getDiskUsage_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, "getDiskUsage failed: unknown result")
+    def __init__(self, login=None, tables=None,):
+        self.login = login
+        self.tables = tables
 
-  def getLocalityGroups(self, login, tableName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.SET:
+                    self.tables = set()
+                    (_etype200, _size197) = iprot.readSetBegin()
+                    for _i201 in range(_size197):
+                        _elem202 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.tables.add(_elem202)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getDiskUsage_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tables is not None:
+            oprot.writeFieldBegin('tables', TType.SET, 2)
+            oprot.writeSetBegin(TType.STRING, len(self.tables))
+            for iter203 in self.tables:
+                oprot.writeString(iter203.encode('utf-8') if sys.version_info[0] == 2 else iter203)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getDiskUsage_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.LIST, 'success', (TType.STRUCT, (DiskUsage, DiskUsage.thrift_spec), False), 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = []
+                    (_etype207, _size204) = iprot.readListBegin()
+                    for _i208 in range(_size204):
+                        _elem209 = DiskUsage()
+                        _elem209.read(iprot)
+                        self.success.append(_elem209)
+                    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)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getDiskUsage_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.LIST, 0)
+            oprot.writeListBegin(TType.STRUCT, len(self.success))
+            for iter210 in self.success:
+                iter210.write(oprot)
+            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()
+        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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getLocalityGroups_args(object):
+    """
+    Attributes:
      - login
      - tableName
     """
-    self.send_getLocalityGroups(login, tableName)
-    return self.recv_getLocalityGroups()
 
-  def send_getLocalityGroups(self, login, tableName):
-    self._oprot.writeMessageBegin('getLocalityGroups', TMessageType.CALL, self._seqid)
-    args = getLocalityGroups_args()
-    args.login = login
-    args.tableName = tableName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+    )
 
-  def recv_getLocalityGroups(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getLocalityGroups_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, "getLocalityGroups failed: unknown result")
+    def __init__(self, login=None, tableName=None,):
+        self.login = login
+        self.tableName = tableName
 
-  def getIteratorSetting(self, login, tableName, iteratorName, scope):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getLocalityGroups_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getLocalityGroups_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.SET, (TType.STRING, 'UTF8', False), False), 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = {}
+                    (_ktype212, _vtype213, _size211) = iprot.readMapBegin()
+                    for _i215 in range(_size211):
+                        _key216 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val217 = set()
+                        (_etype221, _size218) = iprot.readSetBegin()
+                        for _i222 in range(_size218):
+                            _elem223 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                            _val217.add(_elem223)
+                        iprot.readSetEnd()
+                        self.success[_key216] = _val217
+                    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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getLocalityGroups_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.MAP, 0)
+            oprot.writeMapBegin(TType.STRING, TType.SET, len(self.success))
+            for kiter224, viter225 in self.success.items():
+                oprot.writeString(kiter224.encode('utf-8') if sys.version_info[0] == 2 else kiter224)
+                oprot.writeSetBegin(TType.STRING, len(viter225))
+                for iter226 in viter225:
+                    oprot.writeString(iter226.encode('utf-8') if sys.version_info[0] == 2 else iter226)
+                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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getIteratorSetting_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - iteratorName
      - scope
     """
-    self.send_getIteratorSetting(login, tableName, iteratorName, scope)
-    return self.recv_getIteratorSetting()
 
-  def send_getIteratorSetting(self, login, tableName, iteratorName, scope):
-    self._oprot.writeMessageBegin('getIteratorSetting', TMessageType.CALL, self._seqid)
-    args = getIteratorSetting_args()
-    args.login = login
-    args.tableName = tableName
-    args.iteratorName = iteratorName
-    args.scope = scope
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'iteratorName', 'UTF8', None, ),  # 3
+        (4, TType.I32, 'scope', None, None, ),  # 4
+    )
 
-  def recv_getIteratorSetting(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getIteratorSetting_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, "getIteratorSetting failed: unknown result")
+    def __init__(self, login=None, tableName=None, iteratorName=None, scope=None,):
+        self.login = login
+        self.tableName = tableName
+        self.iteratorName = iteratorName
+        self.scope = scope
 
-  def getMaxRow(self, login, tableName, auths, startRow, startInclusive, endRow, endInclusive):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.iteratorName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getIteratorSetting_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.iteratorName is not None:
+            oprot.writeFieldBegin('iteratorName', TType.STRING, 3)
+            oprot.writeString(self.iteratorName.encode('utf-8') if sys.version_info[0] == 2 else self.iteratorName)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getIteratorSetting_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getIteratorSetting_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getMaxRow_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - auths
@@ -1608,24211 +10609,13842 @@
      - endRow
      - endInclusive
     """
-    self.send_getMaxRow(login, tableName, auths, startRow, startInclusive, endRow, endInclusive)
-    return self.recv_getMaxRow()
 
-  def send_getMaxRow(self, login, tableName, auths, startRow, startInclusive, endRow, endInclusive):
-    self._oprot.writeMessageBegin('getMaxRow', TMessageType.CALL, self._seqid)
-    args = getMaxRow_args()
-    args.login = login
-    args.tableName = tableName
-    args.auths = auths
-    args.startRow = startRow
-    args.startInclusive = startInclusive
-    args.endRow = endRow
-    args.endInclusive = endInclusive
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.SET, 'auths', (TType.STRING, 'BINARY', False), None, ),  # 3
+        (4, TType.STRING, 'startRow', 'BINARY', None, ),  # 4
+        (5, TType.BOOL, 'startInclusive', None, None, ),  # 5
+        (6, TType.STRING, 'endRow', 'BINARY', None, ),  # 6
+        (7, TType.BOOL, 'endInclusive', None, None, ),  # 7
+    )
 
-  def recv_getMaxRow(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getMaxRow_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, "getMaxRow failed: unknown result")
+    def __init__(self, login=None, tableName=None, auths=None, startRow=None, startInclusive=None, endRow=None, endInclusive=None,):
+        self.login = login
+        self.tableName = tableName
+        self.auths = auths
+        self.startRow = startRow
+        self.startInclusive = startInclusive
+        self.endRow = endRow
+        self.endInclusive = endInclusive
 
-  def getTableProperties(self, login, tableName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.SET:
+                    self.auths = set()
+                    (_etype230, _size227) = iprot.readSetBegin()
+                    for _i231 in range(_size227):
+                        _elem232 = iprot.readBinary()
+                        self.auths.add(_elem232)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.startRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.BOOL:
+                    self.startInclusive = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 6:
+                if ftype == TType.STRING:
+                    self.endRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 7:
+                if ftype == TType.BOOL:
+                    self.endInclusive = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getMaxRow_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.auths is not None:
+            oprot.writeFieldBegin('auths', TType.SET, 3)
+            oprot.writeSetBegin(TType.STRING, len(self.auths))
+            for iter233 in self.auths:
+                oprot.writeBinary(iter233)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        if self.startRow is not None:
+            oprot.writeFieldBegin('startRow', TType.STRING, 4)
+            oprot.writeBinary(self.startRow)
+            oprot.writeFieldEnd()
+        if self.startInclusive is not None:
+            oprot.writeFieldBegin('startInclusive', TType.BOOL, 5)
+            oprot.writeBool(self.startInclusive)
+            oprot.writeFieldEnd()
+        if self.endRow is not None:
+            oprot.writeFieldBegin('endRow', TType.STRING, 6)
+            oprot.writeBinary(self.endRow)
+            oprot.writeFieldEnd()
+        if self.endInclusive is not None:
+            oprot.writeFieldBegin('endInclusive', TType.BOOL, 7)
+            oprot.writeBool(self.endInclusive)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getMaxRow_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.STRING, 'success', 'BINARY', 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getMaxRow_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.STRING, 0)
+            oprot.writeBinary(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getTableProperties_args(object):
+    """
+    Attributes:
      - login
      - tableName
     """
-    self.send_getTableProperties(login, tableName)
-    return self.recv_getTableProperties()
 
-  def send_getTableProperties(self, login, tableName):
-    self._oprot.writeMessageBegin('getTableProperties', TMessageType.CALL, self._seqid)
-    args = getTableProperties_args()
-    args.login = login
-    args.tableName = tableName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+    )
 
-  def recv_getTableProperties(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getTableProperties_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, "getTableProperties failed: unknown result")
+    def __init__(self, login=None, tableName=None,):
+        self.login = login
+        self.tableName = tableName
 
-  def importDirectory(self, login, tableName, importDir, failureDir, setTime):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getTableProperties_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getTableProperties_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = {}
+                    (_ktype235, _vtype236, _size234) = iprot.readMapBegin()
+                    for _i238 in range(_size234):
+                        _key239 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val240 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.success[_key239] = _val240
+                    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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getTableProperties_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.MAP, 0)
+            oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
+            for kiter241, viter242 in self.success.items():
+                oprot.writeString(kiter241.encode('utf-8') if sys.version_info[0] == 2 else kiter241)
+                oprot.writeString(viter242.encode('utf-8') if sys.version_info[0] == 2 else viter242)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 importDirectory_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - importDir
      - failureDir
      - setTime
     """
-    self.send_importDirectory(login, tableName, importDir, failureDir, setTime)
-    self.recv_importDirectory()
 
-  def send_importDirectory(self, login, tableName, importDir, failureDir, setTime):
-    self._oprot.writeMessageBegin('importDirectory', TMessageType.CALL, self._seqid)
-    args = importDirectory_args()
-    args.login = login
-    args.tableName = tableName
-    args.importDir = importDir
-    args.failureDir = failureDir
-    args.setTime = setTime
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'importDir', 'UTF8', None, ),  # 3
+        (4, TType.STRING, 'failureDir', 'UTF8', None, ),  # 4
+        (5, TType.BOOL, 'setTime', None, None, ),  # 5
+    )
 
-  def recv_importDirectory(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = importDirectory_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.ouch1 is not None:
-      raise result.ouch1
-    if result.ouch3 is not None:
-      raise result.ouch3
-    if result.ouch4 is not None:
-      raise result.ouch4
-    return
+    def __init__(self, login=None, tableName=None, importDir=None, failureDir=None, setTime=None,):
+        self.login = login
+        self.tableName = tableName
+        self.importDir = importDir
+        self.failureDir = failureDir
+        self.setTime = setTime
 
-  def importTable(self, login, tableName, importDir):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.importDir = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.failureDir = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.BOOL:
+                    self.setTime = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('importDirectory_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.importDir is not None:
+            oprot.writeFieldBegin('importDir', TType.STRING, 3)
+            oprot.writeString(self.importDir.encode('utf-8') if sys.version_info[0] == 2 else self.importDir)
+            oprot.writeFieldEnd()
+        if self.failureDir is not None:
+            oprot.writeFieldBegin('failureDir', TType.STRING, 4)
+            oprot.writeString(self.failureDir.encode('utf-8') if sys.version_info[0] == 2 else self.failureDir)
+            oprot.writeFieldEnd()
+        if self.setTime is not None:
+            oprot.writeFieldBegin('setTime', TType.BOOL, 5)
+            oprot.writeBool(self.setTime)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 importDirectory_result(object):
     """
-    Parameters:
+    Attributes:
+     - ouch1
+     - ouch3
+     - ouch4
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'ouch1', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch3', (AccumuloException, AccumuloException.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch4', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ),  # 3
+    )
+
+    def __init__(self, ouch1=None, ouch3=None, ouch4=None,):
+        self.ouch1 = ouch1
+        self.ouch3 = ouch3
+        self.ouch4 = ouch4
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = AccumuloException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch4 = AccumuloSecurityException()
+                    self.ouch4.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('importDirectory_result')
+        if self.ouch1 is not None:
+            oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+            self.ouch1.write(oprot)
+            oprot.writeFieldEnd()
+        if self.ouch3 is not None:
+            oprot.writeFieldBegin('ouch3', TType.STRUCT, 2)
+            self.ouch3.write(oprot)
+            oprot.writeFieldEnd()
+        if self.ouch4 is not None:
+            oprot.writeFieldBegin('ouch4', TType.STRUCT, 3)
+            self.ouch4.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 importTable_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - importDir
     """
-    self.send_importTable(login, tableName, importDir)
-    self.recv_importTable()
 
-  def send_importTable(self, login, tableName, importDir):
-    self._oprot.writeMessageBegin('importTable', TMessageType.CALL, self._seqid)
-    args = importTable_args()
-    args.login = login
-    args.tableName = tableName
-    args.importDir = importDir
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'importDir', 'UTF8', None, ),  # 3
+    )
 
-  def recv_importTable(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = importTable_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 __init__(self, login=None, tableName=None, importDir=None,):
+        self.login = login
+        self.tableName = tableName
+        self.importDir = importDir
 
-  def listSplits(self, login, tableName, maxSplits):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.importDir = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('importTable_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.importDir is not None:
+            oprot.writeFieldBegin('importDir', TType.STRING, 3)
+            oprot.writeString(self.importDir.encode('utf-8') if sys.version_info[0] == 2 else self.importDir)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 importTable_result(object):
     """
-    Parameters:
+    Attributes:
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'ouch1', (TableExistsException, TableExistsException.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (AccumuloException, AccumuloException.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch3', (AccumuloSecurityException, AccumuloSecurityException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableExistsException()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch2 = AccumuloException()
+                    self.ouch2.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = AccumuloSecurityException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('importTable_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 listSplits_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - maxSplits
     """
-    self.send_listSplits(login, tableName, maxSplits)
-    return self.recv_listSplits()
 
-  def send_listSplits(self, login, tableName, maxSplits):
-    self._oprot.writeMessageBegin('listSplits', TMessageType.CALL, self._seqid)
-    args = listSplits_args()
-    args.login = login
-    args.tableName = tableName
-    args.maxSplits = maxSplits
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.I32, 'maxSplits', None, None, ),  # 3
+    )
 
-  def recv_listSplits(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = listSplits_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, "listSplits failed: unknown result")
+    def __init__(self, login=None, tableName=None, maxSplits=None,):
+        self.login = login
+        self.tableName = tableName
+        self.maxSplits = maxSplits
 
-  def listTables(self, login):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.I32:
+                    self.maxSplits = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listSplits_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.maxSplits is not None:
+            oprot.writeFieldBegin('maxSplits', TType.I32, 3)
+            oprot.writeI32(self.maxSplits)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 listSplits_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.LIST, 'success', (TType.STRING, 'BINARY', False), 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = []
+                    (_etype246, _size243) = iprot.readListBegin()
+                    for _i247 in range(_size243):
+                        _elem248 = iprot.readBinary()
+                        self.success.append(_elem248)
+                    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)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listSplits_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.LIST, 0)
+            oprot.writeListBegin(TType.STRING, len(self.success))
+            for iter249 in self.success:
+                oprot.writeBinary(iter249)
+            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()
+        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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 listTables_args(object):
+    """
+    Attributes:
      - login
     """
-    self.send_listTables(login)
-    return self.recv_listTables()
 
-  def send_listTables(self, login):
-    self._oprot.writeMessageBegin('listTables', TMessageType.CALL, self._seqid)
-    args = listTables_args()
-    args.login = login
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+    )
 
-  def recv_listTables(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = listTables_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.success is not None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "listTables failed: unknown result")
+    def __init__(self, login=None,):
+        self.login = login
 
-  def listIterators(self, login, tableName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listTables_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 listTables_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+    """
+
+    thrift_spec = (
+        (0, TType.SET, 'success', (TType.STRING, 'UTF8', False), None, ),  # 0
+    )
+
+    def __init__(self, success=None,):
+        self.success = success
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.SET:
+                    self.success = set()
+                    (_etype253, _size250) = iprot.readSetBegin()
+                    for _i254 in range(_size250):
+                        _elem255 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.success.add(_elem255)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listTables_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.SET, 0)
+            oprot.writeSetBegin(TType.STRING, len(self.success))
+            for iter256 in self.success:
+                oprot.writeString(iter256.encode('utf-8') if sys.version_info[0] == 2 else iter256)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 listIterators_args(object):
+    """
+    Attributes:
      - login
      - tableName
     """
-    self.send_listIterators(login, tableName)
-    return self.recv_listIterators()
 
-  def send_listIterators(self, login, tableName):
-    self._oprot.writeMessageBegin('listIterators', TMessageType.CALL, self._seqid)
-    args = listIterators_args()
-    args.login = login
-    args.tableName = tableName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+    )
 
-  def recv_listIterators(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = listIterators_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, "listIterators failed: unknown result")
+    def __init__(self, login=None, tableName=None,):
+        self.login = login
+        self.tableName = tableName
 
-  def listConstraints(self, login, tableName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listIterators_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 listIterators_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.SET, (TType.I32, None, False), False), 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = {}
+                    (_ktype258, _vtype259, _size257) = iprot.readMapBegin()
+                    for _i261 in range(_size257):
+                        _key262 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val263 = set()
+                        (_etype267, _size264) = iprot.readSetBegin()
+                        for _i268 in range(_size264):
+                            _elem269 = iprot.readI32()
+                            _val263.add(_elem269)
+                        iprot.readSetEnd()
+                        self.success[_key262] = _val263
+                    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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listIterators_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.MAP, 0)
+            oprot.writeMapBegin(TType.STRING, TType.SET, len(self.success))
+            for kiter270, viter271 in self.success.items():
+                oprot.writeString(kiter270.encode('utf-8') if sys.version_info[0] == 2 else kiter270)
+                oprot.writeSetBegin(TType.I32, len(viter271))
+                for iter272 in viter271:
+                    oprot.writeI32(iter272)
+                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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 listConstraints_args(object):
+    """
+    Attributes:
      - login
      - tableName
     """
-    self.send_listConstraints(login, tableName)
-    return self.recv_listConstraints()
 
-  def send_listConstraints(self, login, tableName):
-    self._oprot.writeMessageBegin('listConstraints', TMessageType.CALL, self._seqid)
-    args = listConstraints_args()
-    args.login = login
-    args.tableName = tableName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+    )
 
-  def recv_listConstraints(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = listConstraints_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, "listConstraints failed: unknown result")
+    def __init__(self, login=None, tableName=None,):
+        self.login = login
+        self.tableName = tableName
 
-  def mergeTablets(self, login, tableName, startRow, endRow):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listConstraints_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 listConstraints_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.I32, None, False), 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = {}
+                    (_ktype274, _vtype275, _size273) = iprot.readMapBegin()
+                    for _i277 in range(_size273):
+                        _key278 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val279 = iprot.readI32()
+                        self.success[_key278] = _val279
+                    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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listConstraints_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.MAP, 0)
+            oprot.writeMapBegin(TType.STRING, TType.I32, len(self.success))
+            for kiter280, viter281 in self.success.items():
+                oprot.writeString(kiter280.encode('utf-8') if sys.version_info[0] == 2 else kiter280)
+                oprot.writeI32(viter281)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 mergeTablets_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - startRow
      - endRow
     """
-    self.send_mergeTablets(login, tableName, startRow, endRow)
-    self.recv_mergeTablets()
 
-  def send_mergeTablets(self, login, tableName, startRow, endRow):
-    self._oprot.writeMessageBegin('mergeTablets', TMessageType.CALL, self._seqid)
-    args = mergeTablets_args()
-    args.login = login
-    args.tableName = tableName
-    args.startRow = startRow
-    args.endRow = endRow
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'startRow', 'BINARY', None, ),  # 3
+        (4, TType.STRING, 'endRow', 'BINARY', None, ),  # 4
+    )
 
-  def recv_mergeTablets(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = mergeTablets_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 __init__(self, login=None, tableName=None, startRow=None, endRow=None,):
+        self.login = login
+        self.tableName = tableName
+        self.startRow = startRow
+        self.endRow = endRow
 
-  def offlineTable(self, login, tableName, wait):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.startRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.endRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('mergeTablets_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.startRow is not None:
+            oprot.writeFieldBegin('startRow', TType.STRING, 3)
+            oprot.writeBinary(self.startRow)
+            oprot.writeFieldEnd()
+        if self.endRow is not None:
+            oprot.writeFieldBegin('endRow', TType.STRING, 4)
+            oprot.writeBinary(self.endRow)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 mergeTablets_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('mergeTablets_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 offlineTable_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - wait
     """
-    self.send_offlineTable(login, tableName, wait)
-    self.recv_offlineTable()
 
-  def send_offlineTable(self, login, tableName, wait):
-    self._oprot.writeMessageBegin('offlineTable', TMessageType.CALL, self._seqid)
-    args = offlineTable_args()
-    args.login = login
-    args.tableName = tableName
-    args.wait = wait
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.BOOL, 'wait', None, False, ),  # 3
+    )
 
-  def recv_offlineTable(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = offlineTable_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 __init__(self, login=None, tableName=None, wait=thrift_spec[3][4],):
+        self.login = login
+        self.tableName = tableName
+        self.wait = wait
 
-  def onlineTable(self, login, tableName, wait):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.BOOL:
+                    self.wait = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('offlineTable_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.wait is not None:
+            oprot.writeFieldBegin('wait', TType.BOOL, 3)
+            oprot.writeBool(self.wait)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 offlineTable_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('offlineTable_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 onlineTable_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - wait
     """
-    self.send_onlineTable(login, tableName, wait)
-    self.recv_onlineTable()
 
-  def send_onlineTable(self, login, tableName, wait):
-    self._oprot.writeMessageBegin('onlineTable', TMessageType.CALL, self._seqid)
-    args = onlineTable_args()
-    args.login = login
-    args.tableName = tableName
-    args.wait = wait
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.BOOL, 'wait', None, False, ),  # 3
+    )
 
-  def recv_onlineTable(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = onlineTable_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 __init__(self, login=None, tableName=None, wait=thrift_spec[3][4],):
+        self.login = login
+        self.tableName = tableName
+        self.wait = wait
 
-  def removeConstraint(self, login, tableName, constraint):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.BOOL:
+                    self.wait = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('onlineTable_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.wait is not None:
+            oprot.writeFieldBegin('wait', TType.BOOL, 3)
+            oprot.writeBool(self.wait)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 onlineTable_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('onlineTable_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 removeConstraint_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - constraint
     """
-    self.send_removeConstraint(login, tableName, constraint)
-    self.recv_removeConstraint()
 
-  def send_removeConstraint(self, login, tableName, constraint):
-    self._oprot.writeMessageBegin('removeConstraint', TMessageType.CALL, self._seqid)
-    args = removeConstraint_args()
-    args.login = login
-    args.tableName = tableName
-    args.constraint = constraint
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.I32, 'constraint', None, None, ),  # 3
+    )
 
-  def recv_removeConstraint(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = removeConstraint_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 __init__(self, login=None, tableName=None, constraint=None,):
+        self.login = login
+        self.tableName = tableName
+        self.constraint = constraint
 
-  def removeIterator(self, login, tableName, iterName, scopes):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.I32:
+                    self.constraint = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeConstraint_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.constraint is not None:
+            oprot.writeFieldBegin('constraint', TType.I32, 3)
+            oprot.writeI32(self.constraint)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 removeConstraint_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeConstraint_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 removeIterator_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - iterName
      - scopes
     """
-    self.send_removeIterator(login, tableName, iterName, scopes)
-    self.recv_removeIterator()
 
-  def send_removeIterator(self, login, tableName, iterName, scopes):
-    self._oprot.writeMessageBegin('removeIterator', TMessageType.CALL, self._seqid)
-    args = removeIterator_args()
-    args.login = login
-    args.tableName = tableName
-    args.iterName = iterName
-    args.scopes = scopes
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'iterName', 'UTF8', None, ),  # 3
+        (4, TType.SET, 'scopes', (TType.I32, None, False), None, ),  # 4
+    )
 
-  def recv_removeIterator(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = removeIterator_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 __init__(self, login=None, tableName=None, iterName=None, scopes=None,):
+        self.login = login
+        self.tableName = tableName
+        self.iterName = iterName
+        self.scopes = scopes
 
-  def removeTableProperty(self, login, tableName, property):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.iterName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.SET:
+                    self.scopes = set()
+                    (_etype285, _size282) = iprot.readSetBegin()
+                    for _i286 in range(_size282):
+                        _elem287 = iprot.readI32()
+                        self.scopes.add(_elem287)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeIterator_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.iterName is not None:
+            oprot.writeFieldBegin('iterName', TType.STRING, 3)
+            oprot.writeString(self.iterName.encode('utf-8') if sys.version_info[0] == 2 else self.iterName)
+            oprot.writeFieldEnd()
+        if self.scopes is not None:
+            oprot.writeFieldBegin('scopes', TType.SET, 4)
+            oprot.writeSetBegin(TType.I32, len(self.scopes))
+            for iter288 in self.scopes:
+                oprot.writeI32(iter288)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 removeIterator_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeIterator_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 removeTableProperty_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - property
     """
-    self.send_removeTableProperty(login, tableName, property)
-    self.recv_removeTableProperty()
 
-  def send_removeTableProperty(self, login, tableName, property):
-    self._oprot.writeMessageBegin('removeTableProperty', TMessageType.CALL, self._seqid)
-    args = removeTableProperty_args()
-    args.login = login
-    args.tableName = tableName
-    args.property = property
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'property', 'UTF8', None, ),  # 3
+    )
 
-  def recv_removeTableProperty(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = removeTableProperty_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 __init__(self, login=None, tableName=None, property=None,):
+        self.login = login
+        self.tableName = tableName
+        self.property = property
 
-  def renameTable(self, login, oldTableName, newTableName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.property = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeTableProperty_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.property is not None:
+            oprot.writeFieldBegin('property', TType.STRING, 3)
+            oprot.writeString(self.property.encode('utf-8') if sys.version_info[0] == 2 else self.property)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 removeTableProperty_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeTableProperty_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 renameTable_args(object):
+    """
+    Attributes:
      - login
      - oldTableName
      - newTableName
     """
-    self.send_renameTable(login, oldTableName, newTableName)
-    self.recv_renameTable()
 
-  def send_renameTable(self, login, oldTableName, newTableName):
-    self._oprot.writeMessageBegin('renameTable', TMessageType.CALL, self._seqid)
-    args = renameTable_args()
-    args.login = login
-    args.oldTableName = oldTableName
-    args.newTableName = newTableName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'oldTableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'newTableName', 'UTF8', None, ),  # 3
+    )
 
-  def recv_renameTable(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = renameTable_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 __init__(self, login=None, oldTableName=None, newTableName=None,):
+        self.login = login
+        self.oldTableName = oldTableName
+        self.newTableName = newTableName
 
-  def setLocalityGroups(self, login, tableName, groups):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.oldTableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.newTableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('renameTable_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.oldTableName is not None:
+            oprot.writeFieldBegin('oldTableName', TType.STRING, 2)
+            oprot.writeString(self.oldTableName.encode('utf-8') if sys.version_info[0] == 2 else self.oldTableName)
+            oprot.writeFieldEnd()
+        if self.newTableName is not None:
+            oprot.writeFieldBegin('newTableName', TType.STRING, 3)
+            oprot.writeString(self.newTableName.encode('utf-8') if sys.version_info[0] == 2 else self.newTableName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 renameTable_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ),  # 3
+        (4, TType.STRUCT, 'ouch4', (TableExistsException, TableExistsException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRUCT:
+                    self.ouch4 = TableExistsException()
+                    self.ouch4.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('renameTable_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 setLocalityGroups_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - groups
     """
-    self.send_setLocalityGroups(login, tableName, groups)
-    self.recv_setLocalityGroups()
 
-  def send_setLocalityGroups(self, login, tableName, groups):
-    self._oprot.writeMessageBegin('setLocalityGroups', TMessageType.CALL, self._seqid)
-    args = setLocalityGroups_args()
-    args.login = login
-    args.tableName = tableName
-    args.groups = groups
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.MAP, 'groups', (TType.STRING, 'UTF8', TType.SET, (TType.STRING, 'UTF8', False), False), None, ),  # 3
+    )
 
-  def recv_setLocalityGroups(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = setLocalityGroups_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 __init__(self, login=None, tableName=None, groups=None,):
+        self.login = login
+        self.tableName = tableName
+        self.groups = groups
 
-  def setTableProperty(self, login, tableName, property, value):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.MAP:
+                    self.groups = {}
+                    (_ktype290, _vtype291, _size289) = iprot.readMapBegin()
+                    for _i293 in range(_size289):
+                        _key294 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val295 = set()
+                        (_etype299, _size296) = iprot.readSetBegin()
+                        for _i300 in range(_size296):
+                            _elem301 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                            _val295.add(_elem301)
+                        iprot.readSetEnd()
+                        self.groups[_key294] = _val295
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('setLocalityGroups_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.groups is not None:
+            oprot.writeFieldBegin('groups', TType.MAP, 3)
+            oprot.writeMapBegin(TType.STRING, TType.SET, len(self.groups))
+            for kiter302, viter303 in self.groups.items():
+                oprot.writeString(kiter302.encode('utf-8') if sys.version_info[0] == 2 else kiter302)
+                oprot.writeSetBegin(TType.STRING, len(viter303))
+                for iter304 in viter303:
+                    oprot.writeString(iter304.encode('utf-8') if sys.version_info[0] == 2 else iter304)
+                oprot.writeSetEnd()
+            oprot.writeMapEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 setLocalityGroups_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('setLocalityGroups_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 setTableProperty_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - property
      - value
     """
-    self.send_setTableProperty(login, tableName, property, value)
-    self.recv_setTableProperty()
 
-  def send_setTableProperty(self, login, tableName, property, value):
-    self._oprot.writeMessageBegin('setTableProperty', TMessageType.CALL, self._seqid)
-    args = setTableProperty_args()
-    args.login = login
-    args.tableName = tableName
-    args.property = property
-    args.value = value
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'property', 'UTF8', None, ),  # 3
+        (4, TType.STRING, 'value', 'UTF8', None, ),  # 4
+    )
 
-  def recv_setTableProperty(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = setTableProperty_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 __init__(self, login=None, tableName=None, property=None, value=None,):
+        self.login = login
+        self.tableName = tableName
+        self.property = property
+        self.value = value
 
-  def splitRangeByTablets(self, login, tableName, range, maxSplits):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.property = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.value = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('setTableProperty_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.property is not None:
+            oprot.writeFieldBegin('property', TType.STRING, 3)
+            oprot.writeString(self.property.encode('utf-8') if sys.version_info[0] == 2 else self.property)
+            oprot.writeFieldEnd()
+        if self.value is not None:
+            oprot.writeFieldBegin('value', TType.STRING, 4)
+            oprot.writeString(self.value.encode('utf-8') if sys.version_info[0] == 2 else self.value)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 setTableProperty_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('setTableProperty_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 splitRangeByTablets_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - range
      - maxSplits
     """
-    self.send_splitRangeByTablets(login, tableName, range, maxSplits)
-    return self.recv_splitRangeByTablets()
 
-  def send_splitRangeByTablets(self, login, tableName, range, maxSplits):
-    self._oprot.writeMessageBegin('splitRangeByTablets', TMessageType.CALL, self._seqid)
-    args = splitRangeByTablets_args()
-    args.login = login
-    args.tableName = tableName
-    args.range = range
-    args.maxSplits = maxSplits
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRUCT, 'range', (Range, Range.thrift_spec), None, ),  # 3
+        (4, TType.I32, 'maxSplits', None, None, ),  # 4
+    )
 
-  def recv_splitRangeByTablets(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = splitRangeByTablets_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, "splitRangeByTablets failed: unknown result")
+    def __init__(self, login=None, tableName=None, range=None, maxSplits=None,):
+        self.login = login
+        self.tableName = tableName
+        self.range = range
+        self.maxSplits = maxSplits
 
-  def tableExists(self, login, tableName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.range = Range()
+                    self.range.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.I32:
+                    self.maxSplits = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('splitRangeByTablets_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.range is not None:
+            oprot.writeFieldBegin('range', TType.STRUCT, 3)
+            self.range.write(oprot)
+            oprot.writeFieldEnd()
+        if self.maxSplits is not None:
+            oprot.writeFieldBegin('maxSplits', TType.I32, 4)
+            oprot.writeI32(self.maxSplits)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 splitRangeByTablets_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.SET, 'success', (TType.STRUCT, (Range, Range.thrift_spec), False), 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.SET:
+                    self.success = set()
+                    (_etype308, _size305) = iprot.readSetBegin()
+                    for _i309 in range(_size305):
+                        _elem310 = Range()
+                        _elem310.read(iprot)
+                        self.success.add(_elem310)
+                    iprot.readSetEnd()
+                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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('splitRangeByTablets_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.SET, 0)
+            oprot.writeSetBegin(TType.STRUCT, len(self.success))
+            for iter311 in self.success:
+                iter311.write(oprot)
+            oprot.writeSetEnd()
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 tableExists_args(object):
+    """
+    Attributes:
      - login
      - tableName
     """
-    self.send_tableExists(login, tableName)
-    return self.recv_tableExists()
 
-  def send_tableExists(self, login, tableName):
-    self._oprot.writeMessageBegin('tableExists', TMessageType.CALL, self._seqid)
-    args = tableExists_args()
-    args.login = login
-    args.tableName = tableName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+    )
 
-  def recv_tableExists(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = tableExists_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.success is not None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "tableExists failed: unknown result")
+    def __init__(self, login=None, tableName=None,):
+        self.login = login
+        self.tableName = tableName
 
-  def tableIdMap(self, login):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('tableExists_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 tableExists_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+    """
+
+    thrift_spec = (
+        (0, TType.BOOL, 'success', None, None, ),  # 0
+    )
+
+    def __init__(self, success=None,):
+        self.success = success
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('tableExists_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.BOOL, 0)
+            oprot.writeBool(self.success)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 tableIdMap_args(object):
+    """
+    Attributes:
      - login
     """
-    self.send_tableIdMap(login)
-    return self.recv_tableIdMap()
 
-  def send_tableIdMap(self, login):
-    self._oprot.writeMessageBegin('tableIdMap', TMessageType.CALL, self._seqid)
-    args = tableIdMap_args()
-    args.login = login
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+    )
 
-  def recv_tableIdMap(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = tableIdMap_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.success is not None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "tableIdMap failed: unknown result")
+    def __init__(self, login=None,):
+        self.login = login
 
-  def testTableClassLoad(self, login, tableName, className, asTypeName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('tableIdMap_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 tableIdMap_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), None, ),  # 0
+    )
+
+    def __init__(self, success=None,):
+        self.success = success
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = {}
+                    (_ktype313, _vtype314, _size312) = iprot.readMapBegin()
+                    for _i316 in range(_size312):
+                        _key317 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val318 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.success[_key317] = _val318
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('tableIdMap_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.MAP, 0)
+            oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
+            for kiter319, viter320 in self.success.items():
+                oprot.writeString(kiter319.encode('utf-8') if sys.version_info[0] == 2 else kiter319)
+                oprot.writeString(viter320.encode('utf-8') if sys.version_info[0] == 2 else viter320)
+            oprot.writeMapEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 testTableClassLoad_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - className
      - asTypeName
     """
-    self.send_testTableClassLoad(login, tableName, className, asTypeName)
-    return self.recv_testTableClassLoad()
 
-  def send_testTableClassLoad(self, login, tableName, className, asTypeName):
-    self._oprot.writeMessageBegin('testTableClassLoad', TMessageType.CALL, self._seqid)
-    args = testTableClassLoad_args()
-    args.login = login
-    args.tableName = tableName
-    args.className = className
-    args.asTypeName = asTypeName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'className', 'UTF8', None, ),  # 3
+        (4, TType.STRING, 'asTypeName', 'UTF8', None, ),  # 4
+    )
 
-  def recv_testTableClassLoad(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = testTableClassLoad_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, "testTableClassLoad failed: unknown result")
+    def __init__(self, login=None, tableName=None, className=None, asTypeName=None,):
+        self.login = login
+        self.tableName = tableName
+        self.className = className
+        self.asTypeName = asTypeName
 
-  def pingTabletServer(self, login, tserver):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.className = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.asTypeName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('testTableClassLoad_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.className is not None:
+            oprot.writeFieldBegin('className', TType.STRING, 3)
+            oprot.writeString(self.className.encode('utf-8') if sys.version_info[0] == 2 else self.className)
+            oprot.writeFieldEnd()
+        if self.asTypeName is not None:
+            oprot.writeFieldBegin('asTypeName', TType.STRING, 4)
+            oprot.writeString(self.asTypeName.encode('utf-8') if sys.version_info[0] == 2 else self.asTypeName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 testTableClassLoad_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('testTableClassLoad_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 pingTabletServer_args(object):
+    """
+    Attributes:
      - login
      - tserver
     """
-    self.send_pingTabletServer(login, tserver)
-    self.recv_pingTabletServer()
 
-  def send_pingTabletServer(self, login, tserver):
-    self._oprot.writeMessageBegin('pingTabletServer', TMessageType.CALL, self._seqid)
-    args = pingTabletServer_args()
-    args.login = login
-    args.tserver = tserver
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tserver', 'UTF8', None, ),  # 2
+    )
 
-  def recv_pingTabletServer(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = pingTabletServer_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 __init__(self, login=None, tserver=None,):
+        self.login = login
+        self.tserver = tserver
 
-  def getActiveScans(self, login, tserver):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tserver = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('pingTabletServer_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tserver is not None:
+            oprot.writeFieldBegin('tserver', TType.STRING, 2)
+            oprot.writeString(self.tserver.encode('utf-8') if sys.version_info[0] == 2 else self.tserver)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 pingTabletServer_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('pingTabletServer_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getActiveScans_args(object):
+    """
+    Attributes:
      - login
      - tserver
     """
-    self.send_getActiveScans(login, tserver)
-    return self.recv_getActiveScans()
 
-  def send_getActiveScans(self, login, tserver):
-    self._oprot.writeMessageBegin('getActiveScans', TMessageType.CALL, self._seqid)
-    args = getActiveScans_args()
-    args.login = login
-    args.tserver = tserver
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tserver', 'UTF8', None, ),  # 2
+    )
 
-  def recv_getActiveScans(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getActiveScans_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, "getActiveScans failed: unknown result")
+    def __init__(self, login=None, tserver=None,):
+        self.login = login
+        self.tserver = tserver
 
-  def getActiveCompactions(self, login, tserver):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tserver = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getActiveScans_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tserver is not None:
+            oprot.writeFieldBegin('tserver', TType.STRING, 2)
+            oprot.writeString(self.tserver.encode('utf-8') if sys.version_info[0] == 2 else self.tserver)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getActiveScans_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+    """
+
+    thrift_spec = (
+        (0, TType.LIST, 'success', (TType.STRUCT, (ActiveScan, ActiveScan.thrift_spec), False), 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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = []
+                    (_etype324, _size321) = iprot.readListBegin()
+                    for _i325 in range(_size321):
+                        _elem326 = ActiveScan()
+                        _elem326.read(iprot)
+                        self.success.append(_elem326)
+                    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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getActiveScans_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.LIST, 0)
+            oprot.writeListBegin(TType.STRUCT, len(self.success))
+            for iter327 in self.success:
+                iter327.write(oprot)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getActiveCompactions_args(object):
+    """
+    Attributes:
      - login
      - tserver
     """
-    self.send_getActiveCompactions(login, tserver)
-    return self.recv_getActiveCompactions()
 
-  def send_getActiveCompactions(self, login, tserver):
-    self._oprot.writeMessageBegin('getActiveCompactions', TMessageType.CALL, self._seqid)
-    args = getActiveCompactions_args()
-    args.login = login
-    args.tserver = tserver
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tserver', 'UTF8', None, ),  # 2
+    )
 
-  def recv_getActiveCompactions(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getActiveCompactions_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, "getActiveCompactions failed: unknown result")
+    def __init__(self, login=None, tserver=None,):
+        self.login = login
+        self.tserver = tserver
 
-  def getSiteConfiguration(self, login):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tserver = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getActiveCompactions_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tserver is not None:
+            oprot.writeFieldBegin('tserver', TType.STRING, 2)
+            oprot.writeString(self.tserver.encode('utf-8') if sys.version_info[0] == 2 else self.tserver)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getActiveCompactions_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+    """
+
+    thrift_spec = (
+        (0, TType.LIST, 'success', (TType.STRUCT, (ActiveCompaction, ActiveCompaction.thrift_spec), False), 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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = []
+                    (_etype331, _size328) = iprot.readListBegin()
+                    for _i332 in range(_size328):
+                        _elem333 = ActiveCompaction()
+                        _elem333.read(iprot)
+                        self.success.append(_elem333)
+                    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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getActiveCompactions_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.LIST, 0)
+            oprot.writeListBegin(TType.STRUCT, len(self.success))
+            for iter334 in self.success:
+                iter334.write(oprot)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getSiteConfiguration_args(object):
+    """
+    Attributes:
      - login
     """
-    self.send_getSiteConfiguration(login)
-    return self.recv_getSiteConfiguration()
 
-  def send_getSiteConfiguration(self, login):
-    self._oprot.writeMessageBegin('getSiteConfiguration', TMessageType.CALL, self._seqid)
-    args = getSiteConfiguration_args()
-    args.login = login
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+    )
 
-  def recv_getSiteConfiguration(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getSiteConfiguration_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, "getSiteConfiguration failed: unknown result")
+    def __init__(self, login=None,):
+        self.login = login
 
-  def getSystemConfiguration(self, login):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getSiteConfiguration_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getSiteConfiguration_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), 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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = {}
+                    (_ktype336, _vtype337, _size335) = iprot.readMapBegin()
+                    for _i339 in range(_size335):
+                        _key340 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val341 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.success[_key340] = _val341
+                    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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getSiteConfiguration_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.MAP, 0)
+            oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
+            for kiter342, viter343 in self.success.items():
+                oprot.writeString(kiter342.encode('utf-8') if sys.version_info[0] == 2 else kiter342)
+                oprot.writeString(viter343.encode('utf-8') if sys.version_info[0] == 2 else viter343)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getSystemConfiguration_args(object):
+    """
+    Attributes:
      - login
     """
-    self.send_getSystemConfiguration(login)
-    return self.recv_getSystemConfiguration()
 
-  def send_getSystemConfiguration(self, login):
-    self._oprot.writeMessageBegin('getSystemConfiguration', TMessageType.CALL, self._seqid)
-    args = getSystemConfiguration_args()
-    args.login = login
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+    )
 
-  def recv_getSystemConfiguration(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getSystemConfiguration_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, "getSystemConfiguration failed: unknown result")
+    def __init__(self, login=None,):
+        self.login = login
 
-  def getTabletServers(self, login):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getSystemConfiguration_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getSystemConfiguration_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), 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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = {}
+                    (_ktype345, _vtype346, _size344) = iprot.readMapBegin()
+                    for _i348 in range(_size344):
+                        _key349 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val350 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.success[_key349] = _val350
+                    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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getSystemConfiguration_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.MAP, 0)
+            oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
+            for kiter351, viter352 in self.success.items():
+                oprot.writeString(kiter351.encode('utf-8') if sys.version_info[0] == 2 else kiter351)
+                oprot.writeString(viter352.encode('utf-8') if sys.version_info[0] == 2 else viter352)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getTabletServers_args(object):
+    """
+    Attributes:
      - login
     """
-    self.send_getTabletServers(login)
-    return self.recv_getTabletServers()
 
-  def send_getTabletServers(self, login):
-    self._oprot.writeMessageBegin('getTabletServers', TMessageType.CALL, self._seqid)
-    args = getTabletServers_args()
-    args.login = login
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+    )
 
-  def recv_getTabletServers(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getTabletServers_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.success is not None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getTabletServers failed: unknown result")
+    def __init__(self, login=None,):
+        self.login = login
 
-  def removeProperty(self, login, property):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getTabletServers_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getTabletServers_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+    """
+
+    thrift_spec = (
+        (0, TType.LIST, 'success', (TType.STRING, 'UTF8', False), None, ),  # 0
+    )
+
+    def __init__(self, success=None,):
+        self.success = success
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = []
+                    (_etype356, _size353) = iprot.readListBegin()
+                    for _i357 in range(_size353):
+                        _elem358 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.success.append(_elem358)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getTabletServers_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.LIST, 0)
+            oprot.writeListBegin(TType.STRING, len(self.success))
+            for iter359 in self.success:
+                oprot.writeString(iter359.encode('utf-8') if sys.version_info[0] == 2 else iter359)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 removeProperty_args(object):
+    """
+    Attributes:
      - login
      - property
     """
-    self.send_removeProperty(login, property)
-    self.recv_removeProperty()
 
-  def send_removeProperty(self, login, property):
-    self._oprot.writeMessageBegin('removeProperty', TMessageType.CALL, self._seqid)
-    args = removeProperty_args()
-    args.login = login
-    args.property = property
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'property', 'UTF8', None, ),  # 2
+    )
 
-  def recv_removeProperty(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = removeProperty_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 __init__(self, login=None, property=None,):
+        self.login = login
+        self.property = property
 
-  def setProperty(self, login, property, value):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.property = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeProperty_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.property is not None:
+            oprot.writeFieldBegin('property', TType.STRING, 2)
+            oprot.writeString(self.property.encode('utf-8') if sys.version_info[0] == 2 else self.property)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 removeProperty_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeProperty_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 setProperty_args(object):
+    """
+    Attributes:
      - login
      - property
      - value
     """
-    self.send_setProperty(login, property, value)
-    self.recv_setProperty()
 
-  def send_setProperty(self, login, property, value):
-    self._oprot.writeMessageBegin('setProperty', TMessageType.CALL, self._seqid)
-    args = setProperty_args()
-    args.login = login
-    args.property = property
-    args.value = value
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'property', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'value', 'UTF8', None, ),  # 3
+    )
 
-  def recv_setProperty(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = setProperty_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 __init__(self, login=None, property=None, value=None,):
+        self.login = login
+        self.property = property
+        self.value = value
 
-  def testClassLoad(self, login, className, asTypeName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.property = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.value = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('setProperty_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.property is not None:
+            oprot.writeFieldBegin('property', TType.STRING, 2)
+            oprot.writeString(self.property.encode('utf-8') if sys.version_info[0] == 2 else self.property)
+            oprot.writeFieldEnd()
+        if self.value is not None:
+            oprot.writeFieldBegin('value', TType.STRING, 3)
+            oprot.writeString(self.value.encode('utf-8') if sys.version_info[0] == 2 else self.value)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 setProperty_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('setProperty_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 testClassLoad_args(object):
+    """
+    Attributes:
      - login
      - className
      - asTypeName
     """
-    self.send_testClassLoad(login, className, asTypeName)
-    return self.recv_testClassLoad()
 
-  def send_testClassLoad(self, login, className, asTypeName):
-    self._oprot.writeMessageBegin('testClassLoad', TMessageType.CALL, self._seqid)
-    args = testClassLoad_args()
-    args.login = login
-    args.className = className
-    args.asTypeName = asTypeName
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'className', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'asTypeName', 'UTF8', None, ),  # 3
+    )
 
-  def recv_testClassLoad(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = testClassLoad_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, "testClassLoad failed: unknown result")
+    def __init__(self, login=None, className=None, asTypeName=None,):
+        self.login = login
+        self.className = className
+        self.asTypeName = asTypeName
 
-  def authenticateUser(self, login, user, properties):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.className = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.asTypeName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('testClassLoad_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.className is not None:
+            oprot.writeFieldBegin('className', TType.STRING, 2)
+            oprot.writeString(self.className.encode('utf-8') if sys.version_info[0] == 2 else self.className)
+            oprot.writeFieldEnd()
+        if self.asTypeName is not None:
+            oprot.writeFieldBegin('asTypeName', TType.STRING, 3)
+            oprot.writeString(self.asTypeName.encode('utf-8') if sys.version_info[0] == 2 else self.asTypeName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 testClassLoad_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('testClassLoad_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 authenticateUser_args(object):
+    """
+    Attributes:
      - login
      - user
      - properties
     """
-    self.send_authenticateUser(login, user, properties)
-    return self.recv_authenticateUser()
 
-  def send_authenticateUser(self, login, user, properties):
-    self._oprot.writeMessageBegin('authenticateUser', TMessageType.CALL, self._seqid)
-    args = authenticateUser_args()
-    args.login = login
-    args.user = user
-    args.properties = properties
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.MAP, 'properties', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), None, ),  # 3
+    )
 
-  def recv_authenticateUser(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = authenticateUser_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, "authenticateUser failed: unknown result")
+    def __init__(self, login=None, user=None, properties=None,):
+        self.login = login
+        self.user = user
+        self.properties = properties
 
-  def changeUserAuthorizations(self, login, user, authorizations):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.MAP:
+                    self.properties = {}
+                    (_ktype361, _vtype362, _size360) = iprot.readMapBegin()
+                    for _i364 in range(_size360):
+                        _key365 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val366 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.properties[_key365] = _val366
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('authenticateUser_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.properties is not None:
+            oprot.writeFieldBegin('properties', TType.MAP, 3)
+            oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.properties))
+            for kiter367, viter368 in self.properties.items():
+                oprot.writeString(kiter367.encode('utf-8') if sys.version_info[0] == 2 else kiter367)
+                oprot.writeString(viter368.encode('utf-8') if sys.version_info[0] == 2 else viter368)
+            oprot.writeMapEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 authenticateUser_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('authenticateUser_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 changeUserAuthorizations_args(object):
+    """
+    Attributes:
      - login
      - user
      - authorizations
     """
-    self.send_changeUserAuthorizations(login, user, authorizations)
-    self.recv_changeUserAuthorizations()
 
-  def send_changeUserAuthorizations(self, login, user, authorizations):
-    self._oprot.writeMessageBegin('changeUserAuthorizations', TMessageType.CALL, self._seqid)
-    args = changeUserAuthorizations_args()
-    args.login = login
-    args.user = user
-    args.authorizations = authorizations
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.SET, 'authorizations', (TType.STRING, 'BINARY', False), None, ),  # 3
+    )
 
-  def recv_changeUserAuthorizations(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = changeUserAuthorizations_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 __init__(self, login=None, user=None, authorizations=None,):
+        self.login = login
+        self.user = user
+        self.authorizations = authorizations
 
-  def changeLocalUserPassword(self, login, user, password):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.SET:
+                    self.authorizations = set()
+                    (_etype372, _size369) = iprot.readSetBegin()
+                    for _i373 in range(_size369):
+                        _elem374 = iprot.readBinary()
+                        self.authorizations.add(_elem374)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('changeUserAuthorizations_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.authorizations is not None:
+            oprot.writeFieldBegin('authorizations', TType.SET, 3)
+            oprot.writeSetBegin(TType.STRING, len(self.authorizations))
+            for iter375 in self.authorizations:
+                oprot.writeBinary(iter375)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 changeUserAuthorizations_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('changeUserAuthorizations_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 changeLocalUserPassword_args(object):
+    """
+    Attributes:
      - login
      - user
      - password
     """
-    self.send_changeLocalUserPassword(login, user, password)
-    self.recv_changeLocalUserPassword()
 
-  def send_changeLocalUserPassword(self, login, user, password):
-    self._oprot.writeMessageBegin('changeLocalUserPassword', TMessageType.CALL, self._seqid)
-    args = changeLocalUserPassword_args()
-    args.login = login
-    args.user = user
-    args.password = password
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'password', 'BINARY', None, ),  # 3
+    )
 
-  def recv_changeLocalUserPassword(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = changeLocalUserPassword_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 __init__(self, login=None, user=None, password=None,):
+        self.login = login
+        self.user = user
+        self.password = password
 
-  def createLocalUser(self, login, user, password):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.password = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('changeLocalUserPassword_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.password is not None:
+            oprot.writeFieldBegin('password', TType.STRING, 3)
+            oprot.writeBinary(self.password)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 changeLocalUserPassword_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('changeLocalUserPassword_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createLocalUser_args(object):
+    """
+    Attributes:
      - login
      - user
      - password
     """
-    self.send_createLocalUser(login, user, password)
-    self.recv_createLocalUser()
 
-  def send_createLocalUser(self, login, user, password):
-    self._oprot.writeMessageBegin('createLocalUser', TMessageType.CALL, self._seqid)
-    args = createLocalUser_args()
-    args.login = login
-    args.user = user
-    args.password = password
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'password', 'BINARY', None, ),  # 3
+    )
 
-  def recv_createLocalUser(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = createLocalUser_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 __init__(self, login=None, user=None, password=None,):
+        self.login = login
+        self.user = user
+        self.password = password
 
-  def dropLocalUser(self, login, user):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.password = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createLocalUser_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.password is not None:
+            oprot.writeFieldBegin('password', TType.STRING, 3)
+            oprot.writeBinary(self.password)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createLocalUser_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createLocalUser_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 dropLocalUser_args(object):
+    """
+    Attributes:
      - login
      - user
     """
-    self.send_dropLocalUser(login, user)
-    self.recv_dropLocalUser()
 
-  def send_dropLocalUser(self, login, user):
-    self._oprot.writeMessageBegin('dropLocalUser', TMessageType.CALL, self._seqid)
-    args = dropLocalUser_args()
-    args.login = login
-    args.user = user
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+    )
 
-  def recv_dropLocalUser(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = dropLocalUser_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 __init__(self, login=None, user=None,):
+        self.login = login
+        self.user = user
 
-  def getUserAuthorizations(self, login, user):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('dropLocalUser_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 dropLocalUser_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('dropLocalUser_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getUserAuthorizations_args(object):
+    """
+    Attributes:
      - login
      - user
     """
-    self.send_getUserAuthorizations(login, user)
-    return self.recv_getUserAuthorizations()
 
-  def send_getUserAuthorizations(self, login, user):
-    self._oprot.writeMessageBegin('getUserAuthorizations', TMessageType.CALL, self._seqid)
-    args = getUserAuthorizations_args()
-    args.login = login
-    args.user = user
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+    )
 
-  def recv_getUserAuthorizations(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getUserAuthorizations_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, "getUserAuthorizations failed: unknown result")
+    def __init__(self, login=None, user=None,):
+        self.login = login
+        self.user = user
 
-  def grantSystemPermission(self, login, user, perm):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getUserAuthorizations_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getUserAuthorizations_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+    """
+
+    thrift_spec = (
+        (0, TType.LIST, 'success', (TType.STRING, 'BINARY', False), 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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = []
+                    (_etype379, _size376) = iprot.readListBegin()
+                    for _i380 in range(_size376):
+                        _elem381 = iprot.readBinary()
+                        self.success.append(_elem381)
+                    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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getUserAuthorizations_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.LIST, 0)
+            oprot.writeListBegin(TType.STRING, len(self.success))
+            for iter382 in self.success:
+                oprot.writeBinary(iter382)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 grantSystemPermission_args(object):
+    """
+    Attributes:
      - login
      - user
      - perm
     """
-    self.send_grantSystemPermission(login, user, perm)
-    self.recv_grantSystemPermission()
 
-  def send_grantSystemPermission(self, login, user, perm):
-    self._oprot.writeMessageBegin('grantSystemPermission', TMessageType.CALL, self._seqid)
-    args = grantSystemPermission_args()
-    args.login = login
-    args.user = user
-    args.perm = perm
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.I32, 'perm', None, None, ),  # 3
+    )
 
-  def recv_grantSystemPermission(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = grantSystemPermission_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 __init__(self, login=None, user=None, perm=None,):
+        self.login = login
+        self.user = user
+        self.perm = perm
 
-  def grantTablePermission(self, login, user, table, perm):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('grantSystemPermission_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.perm is not None:
+            oprot.writeFieldBegin('perm', TType.I32, 3)
+            oprot.writeI32(self.perm)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 grantSystemPermission_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('grantSystemPermission_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 grantTablePermission_args(object):
+    """
+    Attributes:
      - login
      - user
      - table
      - perm
     """
-    self.send_grantTablePermission(login, user, table, perm)
-    self.recv_grantTablePermission()
 
-  def send_grantTablePermission(self, login, user, table, perm):
-    self._oprot.writeMessageBegin('grantTablePermission', TMessageType.CALL, self._seqid)
-    args = grantTablePermission_args()
-    args.login = login
-    args.user = user
-    args.table = table
-    args.perm = perm
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'table', 'UTF8', None, ),  # 3
+        (4, TType.I32, 'perm', None, None, ),  # 4
+    )
 
-  def recv_grantTablePermission(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = grantTablePermission_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 __init__(self, login=None, user=None, table=None, perm=None,):
+        self.login = login
+        self.user = user
+        self.table = table
+        self.perm = perm
 
-  def hasSystemPermission(self, login, user, perm):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.table = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('grantTablePermission_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.table is not None:
+            oprot.writeFieldBegin('table', TType.STRING, 3)
+            oprot.writeString(self.table.encode('utf-8') if sys.version_info[0] == 2 else self.table)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 grantTablePermission_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('grantTablePermission_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 hasSystemPermission_args(object):
+    """
+    Attributes:
      - login
      - user
      - perm
     """
-    self.send_hasSystemPermission(login, user, perm)
-    return self.recv_hasSystemPermission()
 
-  def send_hasSystemPermission(self, login, user, perm):
-    self._oprot.writeMessageBegin('hasSystemPermission', TMessageType.CALL, self._seqid)
-    args = hasSystemPermission_args()
-    args.login = login
-    args.user = user
-    args.perm = perm
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.I32, 'perm', None, None, ),  # 3
+    )
 
-  def recv_hasSystemPermission(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = hasSystemPermission_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, "hasSystemPermission failed: unknown result")
+    def __init__(self, login=None, user=None, perm=None,):
+        self.login = login
+        self.user = user
+        self.perm = perm
 
-  def hasTablePermission(self, login, user, table, perm):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('hasSystemPermission_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.perm is not None:
+            oprot.writeFieldBegin('perm', TType.I32, 3)
+            oprot.writeI32(self.perm)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 hasSystemPermission_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('hasSystemPermission_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 hasTablePermission_args(object):
+    """
+    Attributes:
      - login
      - user
      - table
      - perm
     """
-    self.send_hasTablePermission(login, user, table, perm)
-    return self.recv_hasTablePermission()
 
-  def send_hasTablePermission(self, login, user, table, perm):
-    self._oprot.writeMessageBegin('hasTablePermission', TMessageType.CALL, self._seqid)
-    args = hasTablePermission_args()
-    args.login = login
-    args.user = user
-    args.table = table
-    args.perm = perm
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'table', 'UTF8', None, ),  # 3
+        (4, TType.I32, 'perm', None, None, ),  # 4
+    )
 
-  def recv_hasTablePermission(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = hasTablePermission_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, "hasTablePermission failed: unknown result")
+    def __init__(self, login=None, user=None, table=None, perm=None,):
+        self.login = login
+        self.user = user
+        self.table = table
+        self.perm = perm
 
-  def listLocalUsers(self, login):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.table = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('hasTablePermission_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.table is not None:
+            oprot.writeFieldBegin('table', TType.STRING, 3)
+            oprot.writeString(self.table.encode('utf-8') if sys.version_info[0] == 2 else self.table)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 hasTablePermission_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('hasTablePermission_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 listLocalUsers_args(object):
+    """
+    Attributes:
      - login
     """
-    self.send_listLocalUsers(login)
-    return self.recv_listLocalUsers()
 
-  def send_listLocalUsers(self, login):
-    self._oprot.writeMessageBegin('listLocalUsers', TMessageType.CALL, self._seqid)
-    args = listLocalUsers_args()
-    args.login = login
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+    )
 
-  def recv_listLocalUsers(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = listLocalUsers_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, "listLocalUsers failed: unknown result")
+    def __init__(self, login=None,):
+        self.login = login
 
-  def revokeSystemPermission(self, login, user, perm):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listLocalUsers_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 listLocalUsers_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.SET, 'success', (TType.STRING, 'UTF8', False), 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.SET:
+                    self.success = set()
+                    (_etype386, _size383) = iprot.readSetBegin()
+                    for _i387 in range(_size383):
+                        _elem388 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.success.add(_elem388)
+                    iprot.readSetEnd()
+                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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listLocalUsers_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.SET, 0)
+            oprot.writeSetBegin(TType.STRING, len(self.success))
+            for iter389 in self.success:
+                oprot.writeString(iter389.encode('utf-8') if sys.version_info[0] == 2 else iter389)
+            oprot.writeSetEnd()
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 revokeSystemPermission_args(object):
+    """
+    Attributes:
      - login
      - user
      - perm
     """
-    self.send_revokeSystemPermission(login, user, perm)
-    self.recv_revokeSystemPermission()
 
-  def send_revokeSystemPermission(self, login, user, perm):
-    self._oprot.writeMessageBegin('revokeSystemPermission', TMessageType.CALL, self._seqid)
-    args = revokeSystemPermission_args()
-    args.login = login
-    args.user = user
-    args.perm = perm
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.I32, 'perm', None, None, ),  # 3
+    )
 
-  def recv_revokeSystemPermission(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = revokeSystemPermission_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 __init__(self, login=None, user=None, perm=None,):
+        self.login = login
+        self.user = user
+        self.perm = perm
 
-  def revokeTablePermission(self, login, user, table, perm):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('revokeSystemPermission_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.perm is not None:
+            oprot.writeFieldBegin('perm', TType.I32, 3)
+            oprot.writeI32(self.perm)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 revokeSystemPermission_result(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('revokeSystemPermission_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 revokeTablePermission_args(object):
+    """
+    Attributes:
      - login
      - user
      - table
      - perm
     """
-    self.send_revokeTablePermission(login, user, table, perm)
-    self.recv_revokeTablePermission()
 
-  def send_revokeTablePermission(self, login, user, table, perm):
-    self._oprot.writeMessageBegin('revokeTablePermission', TMessageType.CALL, self._seqid)
-    args = revokeTablePermission_args()
-    args.login = login
-    args.user = user
-    args.table = table
-    args.perm = perm
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'table', 'UTF8', None, ),  # 3
+        (4, TType.I32, 'perm', None, None, ),  # 4
+    )
 
-  def recv_revokeTablePermission(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = revokeTablePermission_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 __init__(self, login=None, user=None, table=None, perm=None,):
+        self.login = login
+        self.user = user
+        self.table = table
+        self.perm = perm
 
-  def grantNamespacePermission(self, login, user, namespaceName, perm):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.table = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('revokeTablePermission_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.table is not None:
+            oprot.writeFieldBegin('table', TType.STRING, 3)
+            oprot.writeString(self.table.encode('utf-8') if sys.version_info[0] == 2 else self.table)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 revokeTablePermission_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('revokeTablePermission_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 3
+        (4, TType.I32, 'perm', None, None, ),  # 4
+    )
 
-  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 __init__(self, login=None, user=None, namespaceName=None, perm=None,):
+        self.login = login
+        self.user = user
+        self.namespaceName = namespaceName
+        self.perm = perm
 
-  def hasNamespacePermission(self, login, user, namespaceName, perm):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('grantNamespacePermission_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 3)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 3
+        (4, TType.I32, 'perm', None, None, ),  # 4
+    )
 
-  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 __init__(self, login=None, user=None, namespaceName=None, perm=None,):
+        self.login = login
+        self.user = user
+        self.namespaceName = namespaceName
+        self.perm = perm
 
-  def revokeNamespacePermission(self, login, user, namespaceName, perm):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('hasNamespacePermission_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 3)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 3
+        (4, TType.I32, 'perm', None, None, ),  # 4
+    )
 
-  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 __init__(self, login=None, user=None, namespaceName=None, perm=None,):
+        self.login = login
+        self.user = user
+        self.namespaceName = namespaceName
+        self.perm = perm
 
-  def createBatchScanner(self, login, tableName, options):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('revokeNamespacePermission_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 3)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createBatchScanner_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - options
     """
-    self.send_createBatchScanner(login, tableName, options)
-    return self.recv_createBatchScanner()
 
-  def send_createBatchScanner(self, login, tableName, options):
-    self._oprot.writeMessageBegin('createBatchScanner', TMessageType.CALL, self._seqid)
-    args = createBatchScanner_args()
-    args.login = login
-    args.tableName = tableName
-    args.options = options
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRUCT, 'options', (BatchScanOptions, BatchScanOptions.thrift_spec), None, ),  # 3
+    )
 
-  def recv_createBatchScanner(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = createBatchScanner_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, "createBatchScanner failed: unknown result")
+    def __init__(self, login=None, tableName=None, options=None,):
+        self.login = login
+        self.tableName = tableName
+        self.options = options
 
-  def createScanner(self, login, tableName, options):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.options = BatchScanOptions()
+                    self.options.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createBatchScanner_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.options is not None:
+            oprot.writeFieldBegin('options', TType.STRUCT, 3)
+            self.options.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createBatchScanner_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.STRING, 'success', 'UTF8', 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createBatchScanner_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.STRING, 0)
+            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createScanner_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - options
     """
-    self.send_createScanner(login, tableName, options)
-    return self.recv_createScanner()
 
-  def send_createScanner(self, login, tableName, options):
-    self._oprot.writeMessageBegin('createScanner', TMessageType.CALL, self._seqid)
-    args = createScanner_args()
-    args.login = login
-    args.tableName = tableName
-    args.options = options
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRUCT, 'options', (ScanOptions, ScanOptions.thrift_spec), None, ),  # 3
+    )
 
-  def recv_createScanner(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = createScanner_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, "createScanner failed: unknown result")
+    def __init__(self, login=None, tableName=None, options=None,):
+        self.login = login
+        self.tableName = tableName
+        self.options = options
 
-  def hasNext(self, scanner):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.options = ScanOptions()
+                    self.options.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createScanner_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.options is not None:
+            oprot.writeFieldBegin('options', TType.STRUCT, 3)
+            self.options.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createScanner_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.STRING, 'success', 'UTF8', 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createScanner_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.STRING, 0)
+            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 hasNext_args(object):
+    """
+    Attributes:
      - scanner
     """
-    self.send_hasNext(scanner)
-    return self.recv_hasNext()
 
-  def send_hasNext(self, scanner):
-    self._oprot.writeMessageBegin('hasNext', TMessageType.CALL, self._seqid)
-    args = hasNext_args()
-    args.scanner = scanner
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'scanner', 'UTF8', None, ),  # 1
+    )
 
-  def recv_hasNext(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = hasNext_result()
-    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")
+    def __init__(self, scanner=None,):
+        self.scanner = scanner
 
-  def nextEntry(self, scanner):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.scanner = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('hasNext_args')
+        if self.scanner is not None:
+            oprot.writeFieldBegin('scanner', TType.STRING, 1)
+            oprot.writeString(self.scanner.encode('utf-8') if sys.version_info[0] == 2 else self.scanner)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 hasNext_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+    """
+
+    thrift_spec = (
+        (0, TType.BOOL, 'success', None, None, ),  # 0
+        (1, TType.STRUCT, 'ouch1', (UnknownScanner, UnknownScanner.thrift_spec), None, ),  # 1
+    )
+
+    def __init__(self, success=None, ouch1=None,):
+        self.success = success
+        self.ouch1 = ouch1
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = UnknownScanner()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('hasNext_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()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 nextEntry_args(object):
+    """
+    Attributes:
      - scanner
     """
-    self.send_nextEntry(scanner)
-    return self.recv_nextEntry()
 
-  def send_nextEntry(self, scanner):
-    self._oprot.writeMessageBegin('nextEntry', TMessageType.CALL, self._seqid)
-    args = nextEntry_args()
-    args.scanner = scanner
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'scanner', 'UTF8', None, ),  # 1
+    )
 
-  def recv_nextEntry(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = nextEntry_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, "nextEntry failed: unknown result")
+    def __init__(self, scanner=None,):
+        self.scanner = scanner
 
-  def nextK(self, scanner, k):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.scanner = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('nextEntry_args')
+        if self.scanner is not None:
+            oprot.writeFieldBegin('scanner', TType.STRING, 1)
+            oprot.writeString(self.scanner.encode('utf-8') if sys.version_info[0] == 2 else self.scanner)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 nextEntry_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.STRUCT, 'success', (KeyValueAndPeek, KeyValueAndPeek.thrift_spec), None, ),  # 0
+        (1, TType.STRUCT, 'ouch1', (NoMoreEntriesException, NoMoreEntriesException.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (UnknownScanner, UnknownScanner.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch3', (AccumuloSecurityException, AccumuloSecurityException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = KeyValueAndPeek()
+                    self.success.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 1:
+                if ftype == TType.STRUCT:
+                    self.ouch1 = NoMoreEntriesException()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch2 = UnknownScanner()
+                    self.ouch2.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = AccumuloSecurityException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('nextEntry_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 nextK_args(object):
+    """
+    Attributes:
      - scanner
      - k
     """
-    self.send_nextK(scanner, k)
-    return self.recv_nextK()
 
-  def send_nextK(self, scanner, k):
-    self._oprot.writeMessageBegin('nextK', TMessageType.CALL, self._seqid)
-    args = nextK_args()
-    args.scanner = scanner
-    args.k = k
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'scanner', 'UTF8', None, ),  # 1
+        (2, TType.I32, 'k', None, None, ),  # 2
+    )
 
-  def recv_nextK(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = nextK_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, "nextK failed: unknown result")
+    def __init__(self, scanner=None, k=None,):
+        self.scanner = scanner
+        self.k = k
 
-  def closeScanner(self, scanner):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.scanner = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.I32:
+                    self.k = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('nextK_args')
+        if self.scanner is not None:
+            oprot.writeFieldBegin('scanner', TType.STRING, 1)
+            oprot.writeString(self.scanner.encode('utf-8') if sys.version_info[0] == 2 else self.scanner)
+            oprot.writeFieldEnd()
+        if self.k is not None:
+            oprot.writeFieldBegin('k', TType.I32, 2)
+            oprot.writeI32(self.k)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 nextK_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.STRUCT, 'success', (ScanResult, ScanResult.thrift_spec), None, ),  # 0
+        (1, TType.STRUCT, 'ouch1', (NoMoreEntriesException, NoMoreEntriesException.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (UnknownScanner, UnknownScanner.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch3', (AccumuloSecurityException, AccumuloSecurityException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = ScanResult()
+                    self.success.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 1:
+                if ftype == TType.STRUCT:
+                    self.ouch1 = NoMoreEntriesException()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch2 = UnknownScanner()
+                    self.ouch2.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = AccumuloSecurityException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('nextK_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 closeScanner_args(object):
+    """
+    Attributes:
      - scanner
     """
-    self.send_closeScanner(scanner)
-    self.recv_closeScanner()
 
-  def send_closeScanner(self, scanner):
-    self._oprot.writeMessageBegin('closeScanner', TMessageType.CALL, self._seqid)
-    args = closeScanner_args()
-    args.scanner = scanner
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'scanner', 'UTF8', None, ),  # 1
+    )
 
-  def recv_closeScanner(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = closeScanner_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.ouch1 is not None:
-      raise result.ouch1
-    return
+    def __init__(self, scanner=None,):
+        self.scanner = scanner
 
-  def updateAndFlush(self, login, tableName, cells):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.scanner = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('closeScanner_args')
+        if self.scanner is not None:
+            oprot.writeFieldBegin('scanner', TType.STRING, 1)
+            oprot.writeString(self.scanner.encode('utf-8') if sys.version_info[0] == 2 else self.scanner)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 closeScanner_result(object):
     """
-    Parameters:
+    Attributes:
+     - ouch1
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'ouch1', (UnknownScanner, UnknownScanner.thrift_spec), None, ),  # 1
+    )
+
+    def __init__(self, ouch1=None,):
+        self.ouch1 = ouch1
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = UnknownScanner()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('closeScanner_result')
+        if self.ouch1 is not None:
+            oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
+            self.ouch1.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 updateAndFlush_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - cells
     """
-    self.send_updateAndFlush(login, tableName, cells)
-    self.recv_updateAndFlush()
 
-  def send_updateAndFlush(self, login, tableName, cells):
-    self._oprot.writeMessageBegin('updateAndFlush', TMessageType.CALL, self._seqid)
-    args = updateAndFlush_args()
-    args.login = login
-    args.tableName = tableName
-    args.cells = cells
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.MAP, 'cells', (TType.STRING, 'BINARY', TType.LIST, (TType.STRUCT, (ColumnUpdate, ColumnUpdate.thrift_spec), False), False), None, ),  # 3
+    )
 
-  def recv_updateAndFlush(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = updateAndFlush_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.outch1 is not None:
-      raise result.outch1
-    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 __init__(self, login=None, tableName=None, cells=None,):
+        self.login = login
+        self.tableName = tableName
+        self.cells = cells
 
-  def createWriter(self, login, tableName, opts):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.MAP:
+                    self.cells = {}
+                    (_ktype391, _vtype392, _size390) = iprot.readMapBegin()
+                    for _i394 in range(_size390):
+                        _key395 = iprot.readBinary()
+                        _val396 = []
+                        (_etype400, _size397) = iprot.readListBegin()
+                        for _i401 in range(_size397):
+                            _elem402 = ColumnUpdate()
+                            _elem402.read(iprot)
+                            _val396.append(_elem402)
+                        iprot.readListEnd()
+                        self.cells[_key395] = _val396
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('updateAndFlush_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.cells is not None:
+            oprot.writeFieldBegin('cells', TType.MAP, 3)
+            oprot.writeMapBegin(TType.STRING, TType.LIST, len(self.cells))
+            for kiter403, viter404 in self.cells.items():
+                oprot.writeBinary(kiter403)
+                oprot.writeListBegin(TType.STRUCT, len(viter404))
+                for iter405 in viter404:
+                    iter405.write(oprot)
+                oprot.writeListEnd()
+            oprot.writeMapEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 updateAndFlush_result(object):
     """
-    Parameters:
+    Attributes:
+     - outch1
+     - ouch2
+     - ouch3
+     - ouch4
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'outch1', (AccumuloException, AccumuloException.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch3', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ),  # 3
+        (4, TType.STRUCT, 'ouch4', (MutationsRejectedException, MutationsRejectedException.thrift_spec), None, ),  # 4
+    )
+
+    def __init__(self, outch1=None, ouch2=None, ouch3=None, ouch4=None,):
+        self.outch1 = outch1
+        self.ouch2 = ouch2
+        self.ouch3 = ouch3
+        self.ouch4 = ouch4
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.outch1 = AccumuloException()
+                    self.outch1.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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRUCT:
+                    self.ouch4 = MutationsRejectedException()
+                    self.ouch4.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('updateAndFlush_result')
+        if self.outch1 is not None:
+            oprot.writeFieldBegin('outch1', TType.STRUCT, 1)
+            self.outch1.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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createWriter_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - opts
     """
-    self.send_createWriter(login, tableName, opts)
-    return self.recv_createWriter()
 
-  def send_createWriter(self, login, tableName, opts):
-    self._oprot.writeMessageBegin('createWriter', TMessageType.CALL, self._seqid)
-    args = createWriter_args()
-    args.login = login
-    args.tableName = tableName
-    args.opts = opts
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRUCT, 'opts', (WriterOptions, WriterOptions.thrift_spec), None, ),  # 3
+    )
 
-  def recv_createWriter(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = createWriter_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.success is not None:
-      return result.success
-    if result.outch1 is not None:
-      raise result.outch1
-    if result.ouch2 is not None:
-      raise result.ouch2
-    if result.ouch3 is not None:
-      raise result.ouch3
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "createWriter failed: unknown result")
+    def __init__(self, login=None, tableName=None, opts=None,):
+        self.login = login
+        self.tableName = tableName
+        self.opts = opts
 
-  def update(self, writer, cells):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.opts = WriterOptions()
+                    self.opts.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createWriter_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.opts is not None:
+            oprot.writeFieldBegin('opts', TType.STRUCT, 3)
+            self.opts.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createWriter_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - outch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
+        (1, TType.STRUCT, 'outch1', (AccumuloException, AccumuloException.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch3', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ),  # 3
+    )
+
+    def __init__(self, success=None, outch1=None, ouch2=None, ouch3=None,):
+        self.success = success
+        self.outch1 = outch1
+        self.ouch2 = ouch2
+        self.ouch3 = ouch3
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 1:
+                if ftype == TType.STRUCT:
+                    self.outch1 = AccumuloException()
+                    self.outch1.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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createWriter_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.STRING, 0)
+            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
+            oprot.writeFieldEnd()
+        if self.outch1 is not None:
+            oprot.writeFieldBegin('outch1', TType.STRUCT, 1)
+            self.outch1.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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 update_args(object):
+    """
+    Attributes:
      - writer
      - cells
     """
-    self.send_update(writer, cells)
 
-  def send_update(self, writer, cells):
-    self._oprot.writeMessageBegin('update', TMessageType.ONEWAY, self._seqid)
-    args = update_args()
-    args.writer = writer
-    args.cells = cells
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
-  def flush(self, writer):
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'writer', 'UTF8', None, ),  # 1
+        (2, TType.MAP, 'cells', (TType.STRING, 'BINARY', TType.LIST, (TType.STRUCT, (ColumnUpdate, ColumnUpdate.thrift_spec), False), False), None, ),  # 2
+    )
+
+    def __init__(self, writer=None, cells=None,):
+        self.writer = writer
+        self.cells = cells
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.writer = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.MAP:
+                    self.cells = {}
+                    (_ktype407, _vtype408, _size406) = iprot.readMapBegin()
+                    for _i410 in range(_size406):
+                        _key411 = iprot.readBinary()
+                        _val412 = []
+                        (_etype416, _size413) = iprot.readListBegin()
+                        for _i417 in range(_size413):
+                            _elem418 = ColumnUpdate()
+                            _elem418.read(iprot)
+                            _val412.append(_elem418)
+                        iprot.readListEnd()
+                        self.cells[_key411] = _val412
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('update_args')
+        if self.writer is not None:
+            oprot.writeFieldBegin('writer', TType.STRING, 1)
+            oprot.writeString(self.writer.encode('utf-8') if sys.version_info[0] == 2 else self.writer)
+            oprot.writeFieldEnd()
+        if self.cells is not None:
+            oprot.writeFieldBegin('cells', TType.MAP, 2)
+            oprot.writeMapBegin(TType.STRING, TType.LIST, len(self.cells))
+            for kiter419, viter420 in self.cells.items():
+                oprot.writeBinary(kiter419)
+                oprot.writeListBegin(TType.STRUCT, len(viter420))
+                for iter421 in viter420:
+                    iter421.write(oprot)
+                oprot.writeListEnd()
+            oprot.writeMapEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 flush_args(object):
     """
-    Parameters:
+    Attributes:
      - writer
     """
-    self.send_flush(writer)
-    self.recv_flush()
 
-  def send_flush(self, writer):
-    self._oprot.writeMessageBegin('flush', TMessageType.CALL, self._seqid)
-    args = flush_args()
-    args.writer = writer
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'writer', 'UTF8', None, ),  # 1
+    )
 
-  def recv_flush(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = flush_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 __init__(self, writer=None,):
+        self.writer = writer
 
-  def closeWriter(self, writer):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.writer = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('flush_args')
+        if self.writer is not None:
+            oprot.writeFieldBegin('writer', TType.STRING, 1)
+            oprot.writeString(self.writer.encode('utf-8') if sys.version_info[0] == 2 else self.writer)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 flush_result(object):
     """
-    Parameters:
+    Attributes:
+     - ouch1
+     - ouch2
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'ouch1', (UnknownWriter, UnknownWriter.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (MutationsRejectedException, MutationsRejectedException.thrift_spec), None, ),  # 2
+    )
+
+    def __init__(self, ouch1=None, ouch2=None,):
+        self.ouch1 = ouch1
+        self.ouch2 = ouch2
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = UnknownWriter()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch2 = MutationsRejectedException()
+                    self.ouch2.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('flush_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 closeWriter_args(object):
+    """
+    Attributes:
      - writer
     """
-    self.send_closeWriter(writer)
-    self.recv_closeWriter()
 
-  def send_closeWriter(self, writer):
-    self._oprot.writeMessageBegin('closeWriter', TMessageType.CALL, self._seqid)
-    args = closeWriter_args()
-    args.writer = writer
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'writer', 'UTF8', None, ),  # 1
+    )
 
-  def recv_closeWriter(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = closeWriter_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 __init__(self, writer=None,):
+        self.writer = writer
 
-  def updateRowConditionally(self, login, tableName, row, updates):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.writer = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('closeWriter_args')
+        if self.writer is not None:
+            oprot.writeFieldBegin('writer', TType.STRING, 1)
+            oprot.writeString(self.writer.encode('utf-8') if sys.version_info[0] == 2 else self.writer)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 closeWriter_result(object):
     """
-    Parameters:
+    Attributes:
+     - ouch1
+     - ouch2
+    """
+
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'ouch1', (UnknownWriter, UnknownWriter.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (MutationsRejectedException, MutationsRejectedException.thrift_spec), None, ),  # 2
+    )
+
+    def __init__(self, ouch1=None, ouch2=None,):
+        self.ouch1 = ouch1
+        self.ouch2 = ouch2
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = UnknownWriter()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch2 = MutationsRejectedException()
+                    self.ouch2.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('closeWriter_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 updateRowConditionally_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - row
      - updates
     """
-    self.send_updateRowConditionally(login, tableName, row, updates)
-    return self.recv_updateRowConditionally()
 
-  def send_updateRowConditionally(self, login, tableName, row, updates):
-    self._oprot.writeMessageBegin('updateRowConditionally', TMessageType.CALL, self._seqid)
-    args = updateRowConditionally_args()
-    args.login = login
-    args.tableName = tableName
-    args.row = row
-    args.updates = updates
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'row', 'BINARY', None, ),  # 3
+        (4, TType.STRUCT, 'updates', (ConditionalUpdates, ConditionalUpdates.thrift_spec), None, ),  # 4
+    )
 
-  def recv_updateRowConditionally(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = updateRowConditionally_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, "updateRowConditionally failed: unknown result")
+    def __init__(self, login=None, tableName=None, row=None, updates=None,):
+        self.login = login
+        self.tableName = tableName
+        self.row = row
+        self.updates = updates
 
-  def createConditionalWriter(self, login, tableName, options):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.row = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRUCT:
+                    self.updates = ConditionalUpdates()
+                    self.updates.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('updateRowConditionally_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.row is not None:
+            oprot.writeFieldBegin('row', TType.STRING, 3)
+            oprot.writeBinary(self.row)
+            oprot.writeFieldEnd()
+        if self.updates is not None:
+            oprot.writeFieldBegin('updates', TType.STRUCT, 4)
+            self.updates.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 updateRowConditionally_result(object):
     """
-    Parameters:
+    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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('updateRowConditionally_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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createConditionalWriter_args(object):
+    """
+    Attributes:
      - login
      - tableName
      - options
     """
-    self.send_createConditionalWriter(login, tableName, options)
-    return self.recv_createConditionalWriter()
 
-  def send_createConditionalWriter(self, login, tableName, options):
-    self._oprot.writeMessageBegin('createConditionalWriter', TMessageType.CALL, self._seqid)
-    args = createConditionalWriter_args()
-    args.login = login
-    args.tableName = tableName
-    args.options = options
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'tableName', 'UTF8', None, ),  # 2
+        (3, TType.STRUCT, 'options', (ConditionalWriterOptions, ConditionalWriterOptions.thrift_spec), None, ),  # 3
+    )
 
-  def recv_createConditionalWriter(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = createConditionalWriter_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, "createConditionalWriter failed: unknown result")
+    def __init__(self, login=None, tableName=None, options=None,):
+        self.login = login
+        self.tableName = tableName
+        self.options = options
 
-  def updateRowsConditionally(self, conditionalWriter, updates):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.tableName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.options = ConditionalWriterOptions()
+                    self.options.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createConditionalWriter_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.tableName is not None:
+            oprot.writeFieldBegin('tableName', TType.STRING, 2)
+            oprot.writeString(self.tableName.encode('utf-8') if sys.version_info[0] == 2 else self.tableName)
+            oprot.writeFieldEnd()
+        if self.options is not None:
+            oprot.writeFieldBegin('options', TType.STRUCT, 3)
+            self.options.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 createConditionalWriter_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.STRING, 'success', 'UTF8', 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', (TableNotFoundException, TableNotFoundException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                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 = TableNotFoundException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createConditionalWriter_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.STRING, 0)
+            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 updateRowsConditionally_args(object):
+    """
+    Attributes:
      - conditionalWriter
      - updates
     """
-    self.send_updateRowsConditionally(conditionalWriter, updates)
-    return self.recv_updateRowsConditionally()
 
-  def send_updateRowsConditionally(self, conditionalWriter, updates):
-    self._oprot.writeMessageBegin('updateRowsConditionally', TMessageType.CALL, self._seqid)
-    args = updateRowsConditionally_args()
-    args.conditionalWriter = conditionalWriter
-    args.updates = updates
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'conditionalWriter', 'UTF8', None, ),  # 1
+        (2, TType.MAP, 'updates', (TType.STRING, 'BINARY', TType.STRUCT, (ConditionalUpdates, ConditionalUpdates.thrift_spec), False), None, ),  # 2
+    )
 
-  def recv_updateRowsConditionally(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = updateRowsConditionally_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, "updateRowsConditionally failed: unknown result")
+    def __init__(self, conditionalWriter=None, updates=None,):
+        self.conditionalWriter = conditionalWriter
+        self.updates = updates
 
-  def closeConditionalWriter(self, conditionalWriter):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.conditionalWriter = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.MAP:
+                    self.updates = {}
+                    (_ktype423, _vtype424, _size422) = iprot.readMapBegin()
+                    for _i426 in range(_size422):
+                        _key427 = iprot.readBinary()
+                        _val428 = ConditionalUpdates()
+                        _val428.read(iprot)
+                        self.updates[_key427] = _val428
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('updateRowsConditionally_args')
+        if self.conditionalWriter is not None:
+            oprot.writeFieldBegin('conditionalWriter', TType.STRING, 1)
+            oprot.writeString(self.conditionalWriter.encode('utf-8') if sys.version_info[0] == 2 else self.conditionalWriter)
+            oprot.writeFieldEnd()
+        if self.updates is not None:
+            oprot.writeFieldBegin('updates', TType.MAP, 2)
+            oprot.writeMapBegin(TType.STRING, TType.STRUCT, len(self.updates))
+            for kiter429, viter430 in self.updates.items():
+                oprot.writeBinary(kiter429)
+                viter430.write(oprot)
+            oprot.writeMapEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 updateRowsConditionally_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'BINARY', TType.I32, None, False), None, ),  # 0
+        (1, TType.STRUCT, 'ouch1', (UnknownWriter, UnknownWriter.thrift_spec), None, ),  # 1
+        (2, TType.STRUCT, 'ouch2', (AccumuloException, AccumuloException.thrift_spec), None, ),  # 2
+        (3, TType.STRUCT, 'ouch3', (AccumuloSecurityException, AccumuloSecurityException.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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = {}
+                    (_ktype432, _vtype433, _size431) = iprot.readMapBegin()
+                    for _i435 in range(_size431):
+                        _key436 = iprot.readBinary()
+                        _val437 = iprot.readI32()
+                        self.success[_key436] = _val437
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 1:
+                if ftype == TType.STRUCT:
+                    self.ouch1 = UnknownWriter()
+                    self.ouch1.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.ouch2 = AccumuloException()
+                    self.ouch2.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.ouch3 = AccumuloSecurityException()
+                    self.ouch3.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('updateRowsConditionally_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.MAP, 0)
+            oprot.writeMapBegin(TType.STRING, TType.I32, len(self.success))
+            for kiter438, viter439 in self.success.items():
+                oprot.writeBinary(kiter438)
+                oprot.writeI32(viter439)
+            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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 closeConditionalWriter_args(object):
+    """
+    Attributes:
      - conditionalWriter
     """
-    self.send_closeConditionalWriter(conditionalWriter)
-    self.recv_closeConditionalWriter()
 
-  def send_closeConditionalWriter(self, conditionalWriter):
-    self._oprot.writeMessageBegin('closeConditionalWriter', TMessageType.CALL, self._seqid)
-    args = closeConditionalWriter_args()
-    args.conditionalWriter = conditionalWriter
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'conditionalWriter', 'UTF8', None, ),  # 1
+    )
 
-  def recv_closeConditionalWriter(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = closeConditionalWriter_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    return
+    def __init__(self, conditionalWriter=None,):
+        self.conditionalWriter = conditionalWriter
 
-  def getRowRange(self, row):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.conditionalWriter = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('closeConditionalWriter_args')
+        if self.conditionalWriter is not None:
+            oprot.writeFieldBegin('conditionalWriter', TType.STRING, 1)
+            oprot.writeString(self.conditionalWriter.encode('utf-8') if sys.version_info[0] == 2 else self.conditionalWriter)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 closeConditionalWriter_result(object):
+
+    thrift_spec = (
+    )
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('closeConditionalWriter_result')
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getRowRange_args(object):
     """
-    Parameters:
+    Attributes:
      - row
     """
-    self.send_getRowRange(row)
-    return self.recv_getRowRange()
 
-  def send_getRowRange(self, row):
-    self._oprot.writeMessageBegin('getRowRange', TMessageType.CALL, self._seqid)
-    args = getRowRange_args()
-    args.row = row
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'row', 'BINARY', None, ),  # 1
+    )
 
-  def recv_getRowRange(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getRowRange_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.success is not None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getRowRange failed: unknown result")
+    def __init__(self, row=None,):
+        self.row = row
 
-  def getFollowing(self, key, part):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.row = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getRowRange_args')
+        if self.row is not None:
+            oprot.writeFieldBegin('row', TType.STRING, 1)
+            oprot.writeBinary(self.row)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getRowRange_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+    """
+
+    thrift_spec = (
+        (0, TType.STRUCT, 'success', (Range, Range.thrift_spec), None, ),  # 0
+    )
+
+    def __init__(self, success=None,):
+        self.success = success
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = Range()
+                    self.success.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getRowRange_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.STRUCT, 0)
+            self.success.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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 getFollowing_args(object):
+    """
+    Attributes:
      - key
      - part
     """
-    self.send_getFollowing(key, part)
-    return self.recv_getFollowing()
 
-  def send_getFollowing(self, key, part):
-    self._oprot.writeMessageBegin('getFollowing', TMessageType.CALL, self._seqid)
-    args = getFollowing_args()
-    args.key = key
-    args.part = part
-    args.write(self._oprot)
-    self._oprot.writeMessageEnd()
-    self._oprot.trans.flush()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'key', (Key, Key.thrift_spec), None, ),  # 1
+        (2, TType.I32, 'part', None, None, ),  # 2
+    )
 
-  def recv_getFollowing(self):
-    iprot = self._iprot
-    (fname, mtype, rseqid) = iprot.readMessageBegin()
-    if mtype == TMessageType.EXCEPTION:
-      x = TApplicationException()
-      x.read(iprot)
-      iprot.readMessageEnd()
-      raise x
-    result = getFollowing_result()
-    result.read(iprot)
-    iprot.readMessageEnd()
-    if result.success is not None:
-      return result.success
-    raise TApplicationException(TApplicationException.MISSING_RESULT, "getFollowing failed: unknown result")
+    def __init__(self, key=None, part=None,):
+        self.key = key
+        self.part = part
 
-  def systemNamespace(self):
-    self.send_systemNamespace()
-    return self.recv_systemNamespace()
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.key = Key()
+                    self.key.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.I32:
+                    self.part = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  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 write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getFollowing_args')
+        if self.key is not None:
+            oprot.writeFieldBegin('key', TType.STRUCT, 1)
+            self.key.write(oprot)
+            oprot.writeFieldEnd()
+        if self.part is not None:
+            oprot.writeFieldBegin('part', TType.I32, 2)
+            oprot.writeI32(self.part)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  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 validate(self):
+        return
 
-  def defaultNamespace(self):
-    self.send_defaultNamespace()
-    return self.recv_defaultNamespace()
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  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 __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  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 __ne__(self, other):
+        return not (self == other)
 
-  def listNamespaces(self, login):
+
+class getFollowing_result(object):
     """
-    Parameters:
+    Attributes:
+     - success
+    """
+
+    thrift_spec = (
+        (0, TType.STRUCT, 'success', (Key, Key.thrift_spec), None, ),  # 0
+    )
+
+    def __init__(self, success=None,):
+        self.success = success
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 = Key()
+                    self.success.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getFollowing_result')
+        if self.success is not None:
+            oprot.writeFieldBegin('success', TType.STRUCT, 0)
+            self.success.write(oprot)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+
+    thrift_spec = (
+    )
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('systemNamespace_args')
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
+     - success
+    """
+
+    thrift_spec = (
+        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
+    )
+
+    def __init__(self, success=None,):
+        self.success = success
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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.encode('utf-8') if sys.version_info[0] == 2 else self.success)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+
+    thrift_spec = (
+    )
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('defaultNamespace_args')
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
+     - success
+    """
+
+    thrift_spec = (
+        (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
+    )
+
+    def __init__(self, success=None,):
+        self.success = success
+
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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.encode('utf-8') if sys.version_info[0] == 2 else self.success)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+    )
 
-  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 __init__(self, login=None,):
+        self.login = login
 
-  def namespaceExists(self, login, namespaceName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listNamespaces_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+    """
+
+    thrift_spec = (
+        (0, TType.LIST, 'success', (TType.STRING, 'UTF8', False), 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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 range(_size440):
+                        _elem445 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+    )
 
-  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 __init__(self, login=None, namespaceName=None,):
+        self.login = login
+        self.namespaceName = namespaceName
 
-  def createNamespace(self, login, namespaceName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('namespaceExists_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+    )
 
-  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 __init__(self, login=None, namespaceName=None,):
+        self.login = login
+        self.namespaceName = namespaceName
 
-  def deleteNamespace(self, login, namespaceName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('createNamespace_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+    )
 
-  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 __init__(self, login=None, namespaceName=None,):
+        self.login = login
+        self.namespaceName = namespaceName
 
-  def renameNamespace(self, login, oldNamespaceName, newNamespaceName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('deleteNamespace_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'oldNamespaceName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'newNamespaceName', 'UTF8', None, ),  # 3
+    )
 
-  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 __init__(self, login=None, oldNamespaceName=None, newNamespaceName=None,):
+        self.login = login
+        self.oldNamespaceName = oldNamespaceName
+        self.newNamespaceName = newNamespaceName
 
-  def setNamespaceProperty(self, login, namespaceName, property, value):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.oldNamespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.newNamespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('renameNamespace_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.oldNamespaceName is not None:
+            oprot.writeFieldBegin('oldNamespaceName', TType.STRING, 2)
+            oprot.writeString(self.oldNamespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.oldNamespaceName)
+            oprot.writeFieldEnd()
+        if self.newNamespaceName is not None:
+            oprot.writeFieldBegin('newNamespaceName', TType.STRING, 3)
+            oprot.writeString(self.newNamespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.newNamespaceName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'property', 'UTF8', None, ),  # 3
+        (4, TType.STRING, 'value', 'UTF8', None, ),  # 4
+    )
 
-  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 __init__(self, login=None, namespaceName=None, property=None, value=None,):
+        self.login = login
+        self.namespaceName = namespaceName
+        self.property = property
+        self.value = value
 
-  def removeNamespaceProperty(self, login, namespaceName, property):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.property = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.value = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('setNamespaceProperty_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        if self.property is not None:
+            oprot.writeFieldBegin('property', TType.STRING, 3)
+            oprot.writeString(self.property.encode('utf-8') if sys.version_info[0] == 2 else self.property)
+            oprot.writeFieldEnd()
+        if self.value is not None:
+            oprot.writeFieldBegin('value', TType.STRING, 4)
+            oprot.writeString(self.value.encode('utf-8') if sys.version_info[0] == 2 else self.value)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'property', 'UTF8', None, ),  # 3
+    )
 
-  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 __init__(self, login=None, namespaceName=None, property=None,):
+        self.login = login
+        self.namespaceName = namespaceName
+        self.property = property
 
-  def getNamespaceProperties(self, login, namespaceName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.property = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeNamespaceProperty_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        if self.property is not None:
+            oprot.writeFieldBegin('property', TType.STRING, 3)
+            oprot.writeString(self.property.encode('utf-8') if sys.version_info[0] == 2 else self.property)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+    )
 
-  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 __init__(self, login=None, namespaceName=None,):
+        self.login = login
+        self.namespaceName = namespaceName
 
-  def namespaceIdMap(self, login):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getNamespaceProperties_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), 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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 range(_size447):
+                        _key452 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val453 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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.encode('utf-8') if sys.version_info[0] == 2 else kiter454)
+                oprot.writeString(viter455.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+    )
 
-  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 __init__(self, login=None,):
+        self.login = login
 
-  def attachNamespaceIterator(self, login, namespaceName, setting, scopes):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('namespaceIdMap_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), 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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 range(_size456):
+                        _key461 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val462 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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.encode('utf-8') if sys.version_info[0] == 2 else kiter463)
+                oprot.writeString(viter464.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+        (3, TType.STRUCT, 'setting', (IteratorSetting, IteratorSetting.thrift_spec), None, ),  # 3
+        (4, TType.SET, 'scopes', (TType.I32, None, False), None, ),  # 4
+    )
 
-  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 __init__(self, login=None, namespaceName=None, setting=None, scopes=None,):
+        self.login = login
+        self.namespaceName = namespaceName
+        self.setting = setting
+        self.scopes = scopes
 
-  def removeNamespaceIterator(self, login, namespaceName, name, scopes):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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 range(_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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('attachNamespaceIterator_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'name', 'UTF8', None, ),  # 3
+        (4, TType.SET, 'scopes', (TType.I32, None, False), None, ),  # 4
+    )
 
-  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 __init__(self, login=None, namespaceName=None, name=None, scopes=None,):
+        self.login = login
+        self.namespaceName = namespaceName
+        self.name = name
+        self.scopes = scopes
 
-  def getNamespaceIteratorSetting(self, login, namespaceName, name, scope):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.name = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.SET:
+                    self.scopes = set()
+                    (_etype475, _size472) = iprot.readSetBegin()
+                    for _i476 in range(_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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeNamespaceIterator_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        if self.name is not None:
+            oprot.writeFieldBegin('name', TType.STRING, 3)
+            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'name', 'UTF8', None, ),  # 3
+        (4, TType.I32, 'scope', None, None, ),  # 4
+    )
 
-  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 __init__(self, login=None, namespaceName=None, name=None, scope=None,):
+        self.login = login
+        self.namespaceName = namespaceName
+        self.name = name
+        self.scope = scope
 
-  def listNamespaceIterators(self, login, namespaceName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.name = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('getNamespaceIteratorSetting_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        if self.name is not None:
+            oprot.writeFieldBegin('name', TType.STRING, 3)
+            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+    )
 
-  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 __init__(self, login=None, namespaceName=None,):
+        self.login = login
+        self.namespaceName = namespaceName
 
-  def checkNamespaceIteratorConflicts(self, login, namespaceName, setting, scopes):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listNamespaceIterators_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.SET, (TType.I32, None, False), False), 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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 range(_size479):
+                        _key484 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val485 = set()
+                        (_etype489, _size486) = iprot.readSetBegin()
+                        for _i490 in range(_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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+        (3, TType.STRUCT, 'setting', (IteratorSetting, IteratorSetting.thrift_spec), None, ),  # 3
+        (4, TType.SET, 'scopes', (TType.I32, None, False), None, ),  # 4
+    )
 
-  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 __init__(self, login=None, namespaceName=None, setting=None, scopes=None,):
+        self.login = login
+        self.namespaceName = namespaceName
+        self.setting = setting
+        self.scopes = scopes
 
-  def addNamespaceConstraint(self, login, namespaceName, constraintClassName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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 range(_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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('checkNamespaceIteratorConflicts_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'constraintClassName', 'UTF8', None, ),  # 3
+    )
 
-  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 __init__(self, login=None, namespaceName=None, constraintClassName=None,):
+        self.login = login
+        self.namespaceName = namespaceName
+        self.constraintClassName = constraintClassName
 
-  def removeNamespaceConstraint(self, login, namespaceName, id):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.constraintClassName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('addNamespaceConstraint_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        if self.constraintClassName is not None:
+            oprot.writeFieldBegin('constraintClassName', TType.STRING, 3)
+            oprot.writeString(self.constraintClassName.encode('utf-8') if sys.version_info[0] == 2 else self.constraintClassName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+        (3, TType.I32, 'id', None, None, ),  # 3
+    )
 
-  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 __init__(self, login=None, namespaceName=None, id=None,):
+        self.login = login
+        self.namespaceName = namespaceName
+        self.id = id
 
-  def listNamespaceConstraints(self, login, namespaceName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('removeNamespaceConstraint_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+    )
 
-  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 __init__(self, login=None, namespaceName=None,):
+        self.login = login
+        self.namespaceName = namespaceName
 
-  def testNamespaceClassLoad(self, login, namespaceName, className, asTypeName):
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
+
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('listNamespaceConstraints_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
+
+    def validate(self):
+        return
+
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
     """
-    Parameters:
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
+
+    thrift_spec = (
+        (0, TType.MAP, 'success', (TType.STRING, 'UTF8', TType.I32, None, False), 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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 range(_size502):
+                        _key507 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else 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._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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.encode('utf-8') if sys.version_info[0] == 2 else 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 __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        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(object):
+    """
+    Attributes:
      - 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()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'login', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'namespaceName', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'className', 'UTF8', None, ),  # 3
+        (4, TType.STRING, 'asTypeName', 'UTF8', None, ),  # 4
+    )
 
-  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")
+    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.namespaceName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.className = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.asTypeName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-class Processor(Iface, TProcessor):
-  def __init__(self, handler):
-    self._handler = handler
-    self._processMap = {}
-    self._processMap["login"] = Processor.process_login
-    self._processMap["addConstraint"] = Processor.process_addConstraint
-    self._processMap["addSplits"] = Processor.process_addSplits
-    self._processMap["attachIterator"] = Processor.process_attachIterator
-    self._processMap["checkIteratorConflicts"] = Processor.process_checkIteratorConflicts
-    self._processMap["clearLocatorCache"] = Processor.process_clearLocatorCache
-    self._processMap["cloneTable"] = Processor.process_cloneTable
-    self._processMap["compactTable"] = Processor.process_compactTable
-    self._processMap["cancelCompaction"] = Processor.process_cancelCompaction
-    self._processMap["createTable"] = Processor.process_createTable
-    self._processMap["deleteTable"] = Processor.process_deleteTable
-    self._processMap["deleteRows"] = Processor.process_deleteRows
-    self._processMap["exportTable"] = Processor.process_exportTable
-    self._processMap["flushTable"] = Processor.process_flushTable
-    self._processMap["getDiskUsage"] = Processor.process_getDiskUsage
-    self._processMap["getLocalityGroups"] = Processor.process_getLocalityGroups
-    self._processMap["getIteratorSetting"] = Processor.process_getIteratorSetting
-    self._processMap["getMaxRow"] = Processor.process_getMaxRow
-    self._processMap["getTableProperties"] = Processor.process_getTableProperties
-    self._processMap["importDirectory"] = Processor.process_importDirectory
-    self._processMap["importTable"] = Processor.process_importTable
-    self._processMap["listSplits"] = Processor.process_listSplits
-    self._processMap["listTables"] = Processor.process_listTables
-    self._processMap["listIterators"] = Processor.process_listIterators
-    self._processMap["listConstraints"] = Processor.process_listConstraints
-    self._processMap["mergeTablets"] = Processor.process_mergeTablets
-    self._processMap["offlineTable"] = Processor.process_offlineTable
-    self._processMap["onlineTable"] = Processor.process_onlineTable
-    self._processMap["removeConstraint"] = Processor.process_removeConstraint
-    self._processMap["removeIterator"] = Processor.process_removeIterator
-    self._processMap["removeTableProperty"] = Processor.process_removeTableProperty
-    self._processMap["renameTable"] = Processor.process_renameTable
-    self._processMap["setLocalityGroups"] = Processor.process_setLocalityGroups
-    self._processMap["setTableProperty"] = Processor.process_setTableProperty
-    self._processMap["splitRangeByTablets"] = Processor.process_splitRangeByTablets
-    self._processMap["tableExists"] = Processor.process_tableExists
-    self._processMap["tableIdMap"] = Processor.process_tableIdMap
-    self._processMap["testTableClassLoad"] = Processor.process_testTableClassLoad
-    self._processMap["pingTabletServer"] = Processor.process_pingTabletServer
-    self._processMap["getActiveScans"] = Processor.process_getActiveScans
-    self._processMap["getActiveCompactions"] = Processor.process_getActiveCompactions
-    self._processMap["getSiteConfiguration"] = Processor.process_getSiteConfiguration
-    self._processMap["getSystemConfiguration"] = Processor.process_getSystemConfiguration
-    self._processMap["getTabletServers"] = Processor.process_getTabletServers
-    self._processMap["removeProperty"] = Processor.process_removeProperty
-    self._processMap["setProperty"] = Processor.process_setProperty
-    self._processMap["testClassLoad"] = Processor.process_testClassLoad
-    self._processMap["authenticateUser"] = Processor.process_authenticateUser
-    self._processMap["changeUserAuthorizations"] = Processor.process_changeUserAuthorizations
-    self._processMap["changeLocalUserPassword"] = Processor.process_changeLocalUserPassword
-    self._processMap["createLocalUser"] = Processor.process_createLocalUser
-    self._processMap["dropLocalUser"] = Processor.process_dropLocalUser
-    self._processMap["getUserAuthorizations"] = Processor.process_getUserAuthorizations
-    self._processMap["grantSystemPermission"] = Processor.process_grantSystemPermission
-    self._processMap["grantTablePermission"] = Processor.process_grantTablePermission
-    self._processMap["hasSystemPermission"] = Processor.process_hasSystemPermission
-    self._processMap["hasTablePermission"] = Processor.process_hasTablePermission
-    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
-    self._processMap["nextEntry"] = Processor.process_nextEntry
-    self._processMap["nextK"] = Processor.process_nextK
-    self._processMap["closeScanner"] = Processor.process_closeScanner
-    self._processMap["updateAndFlush"] = Processor.process_updateAndFlush
-    self._processMap["createWriter"] = Processor.process_createWriter
-    self._processMap["update"] = Processor.process_update
-    self._processMap["flush"] = Processor.process_flush
-    self._processMap["closeWriter"] = Processor.process_closeWriter
-    self._processMap["updateRowConditionally"] = Processor.process_updateRowConditionally
-    self._processMap["createConditionalWriter"] = Processor.process_createConditionalWriter
-    self._processMap["updateRowsConditionally"] = Processor.process_updateRowsConditionally
-    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 write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('testNamespaceClassLoad_args')
+        if self.login is not None:
+            oprot.writeFieldBegin('login', TType.STRING, 1)
+            oprot.writeBinary(self.login)
+            oprot.writeFieldEnd()
+        if self.namespaceName is not None:
+            oprot.writeFieldBegin('namespaceName', TType.STRING, 2)
+            oprot.writeString(self.namespaceName.encode('utf-8') if sys.version_info[0] == 2 else self.namespaceName)
+            oprot.writeFieldEnd()
+        if self.className is not None:
+            oprot.writeFieldBegin('className', TType.STRING, 3)
+            oprot.writeString(self.className.encode('utf-8') if sys.version_info[0] == 2 else self.className)
+            oprot.writeFieldEnd()
+        if self.asTypeName is not None:
+            oprot.writeFieldBegin('asTypeName', TType.STRING, 4)
+            oprot.writeString(self.asTypeName.encode('utf-8') if sys.version_info[0] == 2 else self.asTypeName)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def process(self, iprot, oprot):
-    (name, type, seqid) = iprot.readMessageBegin()
-    if name not in self._processMap:
-      iprot.skip(TType.STRUCT)
-      iprot.readMessageEnd()
-      x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))
-      oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
-      x.write(oprot)
-      oprot.writeMessageEnd()
-      oprot.trans.flush()
-      return
-    else:
-      self._processMap[name](self, seqid, iprot, oprot)
-    return True
+    def validate(self):
+        return
 
-  def process_login(self, seqid, iprot, oprot):
-    args = login_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = login_result()
-    try:
-      result.success = self._handler.login(args.principal, args.loginProperties)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    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("login", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def process_addConstraint(self, seqid, iprot, oprot):
-    args = addConstraint_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = addConstraint_result()
-    try:
-      result.success = self._handler.addConstraint(args.login, args.tableName, 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 TableNotFoundException 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("addConstraint", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def process_addSplits(self, seqid, iprot, oprot):
-    args = addSplits_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = addSplits_result()
-    try:
-      self._handler.addSplits(args.login, args.tableName, args.splits)
-      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 TableNotFoundException 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("addSplits", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
+    def __ne__(self, other):
+        return not (self == other)
 
-  def process_attachIterator(self, seqid, iprot, oprot):
-    args = attachIterator_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = attachIterator_result()
-    try:
-      self._handler.attachIterator(args.login, args.tableName, args.setting, args.scopes)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except AccumuloSecurityException as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except AccumuloException as ouch2:
-      msg_type = TMessageType.REPLY
-      result.ouch2 = ouch2
-    except TableNotFoundException 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("attachIterator", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
 
-  def process_checkIteratorConflicts(self, seqid, iprot, oprot):
-    args = checkIteratorConflicts_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = checkIteratorConflicts_result()
-    try:
-      self._handler.checkIteratorConflicts(args.login, args.tableName, args.setting, args.scopes)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except AccumuloSecurityException as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except AccumuloException as ouch2:
-      msg_type = TMessageType.REPLY
-      result.ouch2 = ouch2
-    except TableNotFoundException 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("checkIteratorConflicts", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
+class testNamespaceClassLoad_result(object):
+    """
+    Attributes:
+     - success
+     - ouch1
+     - ouch2
+     - ouch3
+    """
 
-  def process_clearLocatorCache(self, seqid, iprot, oprot):
-    args = clearLocatorCache_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = clearLocatorCache_result()
-    try:
-      self._handler.clearLocatorCache(args.login, args.tableName)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except TableNotFoundException as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    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()
+    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 process_cloneTable(self, seqid, iprot, oprot):
-    args = cloneTable_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = cloneTable_result()
-    try:
-      self._handler.cloneTable(args.login, args.tableName, args.newTableName, args.flush, args.propertiesToSet, args.propertiesToExclude)
-      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 TableNotFoundException as ouch3:
-      msg_type = TMessageType.REPLY
-      result.ouch3 = ouch3
-    except TableExistsException 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("cloneTable", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
+    def __init__(self, success=None, ouch1=None, ouch2=None, ouch3=None,):
+        self.success = success
+        self.ouch1 = ouch1
+        self.ouch2 = ouch2
+        self.ouch3 = ouch3
 
-  def process_compactTable(self, seqid, iprot, oprot):
-    args = compactTable_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = compactTable_result()
-    try:
-      self._handler.compactTable(args.login, args.tableName, args.startRow, args.endRow, args.iterators, args.flush, args.wait, args.compactionStrategy)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except AccumuloSecurityException as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except TableNotFoundException as ouch2:
-      msg_type = TMessageType.REPLY
-      result.ouch2 = ouch2
-    except AccumuloException 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("compactTable", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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 process_cancelCompaction(self, seqid, iprot, oprot):
-    args = cancelCompaction_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = cancelCompaction_result()
-    try:
-      self._handler.cancelCompaction(args.login, args.tableName)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except AccumuloSecurityException as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except TableNotFoundException as ouch2:
-      msg_type = TMessageType.REPLY
-      result.ouch2 = ouch2
-    except AccumuloException 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("cancelCompaction", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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 process_createTable(self, seqid, iprot, oprot):
-    args = createTable_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = createTable_result()
-    try:
-      self._handler.createTable(args.login, args.tableName, args.versioningIter, args.type)
-      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 TableExistsException 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("createTable", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
+    def validate(self):
+        return
 
-  def process_deleteTable(self, seqid, iprot, oprot):
-    args = deleteTable_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = deleteTable_result()
-    try:
-      self._handler.deleteTable(args.login, args.tableName)
-      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 TableNotFoundException 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("deleteTable", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def process_deleteRows(self, seqid, iprot, oprot):
-    args = deleteRows_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = deleteRows_result()
-    try:
-      self._handler.deleteRows(args.login, args.tableName, args.startRow, args.endRow)
-      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 TableNotFoundException 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("deleteRows", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def process_exportTable(self, seqid, iprot, oprot):
-    args = exportTable_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = exportTable_result()
-    try:
-      self._handler.exportTable(args.login, args.tableName, args.exportDir)
-      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 TableNotFoundException 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("exportTable", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_flushTable(self, seqid, iprot, oprot):
-    args = flushTable_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = flushTable_result()
-    try:
-      self._handler.flushTable(args.login, args.tableName, args.startRow, args.endRow, args.wait)
-      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 TableNotFoundException 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("flushTable", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getDiskUsage(self, seqid, iprot, oprot):
-    args = getDiskUsage_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getDiskUsage_result()
-    try:
-      result.success = self._handler.getDiskUsage(args.login, args.tables)
-      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 TableNotFoundException 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("getDiskUsage", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getLocalityGroups(self, seqid, iprot, oprot):
-    args = getLocalityGroups_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getLocalityGroups_result()
-    try:
-      result.success = self._handler.getLocalityGroups(args.login, args.tableName)
-      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 TableNotFoundException 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("getLocalityGroups", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getIteratorSetting(self, seqid, iprot, oprot):
-    args = getIteratorSetting_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getIteratorSetting_result()
-    try:
-      result.success = self._handler.getIteratorSetting(args.login, args.tableName, args.iteratorName, 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 TableNotFoundException 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("getIteratorSetting", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getMaxRow(self, seqid, iprot, oprot):
-    args = getMaxRow_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getMaxRow_result()
-    try:
-      result.success = self._handler.getMaxRow(args.login, args.tableName, args.auths, args.startRow, args.startInclusive, args.endRow, args.endInclusive)
-      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 TableNotFoundException 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("getMaxRow", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getTableProperties(self, seqid, iprot, oprot):
-    args = getTableProperties_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getTableProperties_result()
-    try:
-      result.success = self._handler.getTableProperties(args.login, args.tableName)
-      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 TableNotFoundException 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("getTableProperties", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_importDirectory(self, seqid, iprot, oprot):
-    args = importDirectory_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = importDirectory_result()
-    try:
-      self._handler.importDirectory(args.login, args.tableName, args.importDir, args.failureDir, args.setTime)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except TableNotFoundException as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except AccumuloException as ouch3:
-      msg_type = TMessageType.REPLY
-      result.ouch3 = ouch3
-    except AccumuloSecurityException 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("importDirectory", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_importTable(self, seqid, iprot, oprot):
-    args = importTable_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = importTable_result()
-    try:
-      self._handler.importTable(args.login, args.tableName, args.importDir)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except TableExistsException as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except AccumuloException as ouch2:
-      msg_type = TMessageType.REPLY
-      result.ouch2 = ouch2
-    except AccumuloSecurityException 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("importTable", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_listSplits(self, seqid, iprot, oprot):
-    args = listSplits_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = listSplits_result()
-    try:
-      result.success = self._handler.listSplits(args.login, args.tableName, args.maxSplits)
-      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 TableNotFoundException 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("listSplits", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_listTables(self, seqid, iprot, oprot):
-    args = listTables_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = listTables_result()
-    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()
-
-  def process_listIterators(self, seqid, iprot, oprot):
-    args = listIterators_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = listIterators_result()
-    try:
-      result.success = self._handler.listIterators(args.login, args.tableName)
-      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 TableNotFoundException 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("listIterators", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_listConstraints(self, seqid, iprot, oprot):
-    args = listConstraints_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = listConstraints_result()
-    try:
-      result.success = self._handler.listConstraints(args.login, args.tableName)
-      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 TableNotFoundException 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("listConstraints", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_mergeTablets(self, seqid, iprot, oprot):
-    args = mergeTablets_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = mergeTablets_result()
-    try:
-      self._handler.mergeTablets(args.login, args.tableName, args.startRow, args.endRow)
-      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 TableNotFoundException 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("mergeTablets", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_offlineTable(self, seqid, iprot, oprot):
-    args = offlineTable_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = offlineTable_result()
-    try:
-      self._handler.offlineTable(args.login, args.tableName, args.wait)
-      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 TableNotFoundException 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("offlineTable", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_onlineTable(self, seqid, iprot, oprot):
-    args = onlineTable_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = onlineTable_result()
-    try:
-      self._handler.onlineTable(args.login, args.tableName, args.wait)
-      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 TableNotFoundException 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("onlineTable", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_removeConstraint(self, seqid, iprot, oprot):
-    args = removeConstraint_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = removeConstraint_result()
-    try:
-      self._handler.removeConstraint(args.login, args.tableName, args.constraint)
-      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 TableNotFoundException 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("removeConstraint", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_removeIterator(self, seqid, iprot, oprot):
-    args = removeIterator_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = removeIterator_result()
-    try:
-      self._handler.removeIterator(args.login, args.tableName, args.iterName, 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 TableNotFoundException 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("removeIterator", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_removeTableProperty(self, seqid, iprot, oprot):
-    args = removeTableProperty_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = removeTableProperty_result()
-    try:
-      self._handler.removeTableProperty(args.login, args.tableName, 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 TableNotFoundException 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("removeTableProperty", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_renameTable(self, seqid, iprot, oprot):
-    args = renameTable_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = renameTable_result()
-    try:
-      self._handler.renameTable(args.login, args.oldTableName, args.newTableName)
-      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 TableNotFoundException as ouch3:
-      msg_type = TMessageType.REPLY
-      result.ouch3 = ouch3
-    except TableExistsException 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("renameTable", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_setLocalityGroups(self, seqid, iprot, oprot):
-    args = setLocalityGroups_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = setLocalityGroups_result()
-    try:
-      self._handler.setLocalityGroups(args.login, args.tableName, args.groups)
-      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 TableNotFoundException 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("setLocalityGroups", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_setTableProperty(self, seqid, iprot, oprot):
-    args = setTableProperty_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = setTableProperty_result()
-    try:
-      self._handler.setTableProperty(args.login, args.tableName, 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 TableNotFoundException 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("setTableProperty", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_splitRangeByTablets(self, seqid, iprot, oprot):
-    args = splitRangeByTablets_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = splitRangeByTablets_result()
-    try:
-      result.success = self._handler.splitRangeByTablets(args.login, args.tableName, args.range, args.maxSplits)
-      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 TableNotFoundException 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("splitRangeByTablets", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_tableExists(self, seqid, iprot, oprot):
-    args = tableExists_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = tableExists_result()
-    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()
-
-  def process_tableIdMap(self, seqid, iprot, oprot):
-    args = tableIdMap_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = tableIdMap_result()
-    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()
-
-  def process_testTableClassLoad(self, seqid, iprot, oprot):
-    args = testTableClassLoad_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = testTableClassLoad_result()
-    try:
-      result.success = self._handler.testTableClassLoad(args.login, args.tableName, 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 TableNotFoundException 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("testTableClassLoad", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_pingTabletServer(self, seqid, iprot, oprot):
-    args = pingTabletServer_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = pingTabletServer_result()
-    try:
-      self._handler.pingTabletServer(args.login, args.tserver)
-      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("pingTabletServer", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getActiveScans(self, seqid, iprot, oprot):
-    args = getActiveScans_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getActiveScans_result()
-    try:
-      result.success = self._handler.getActiveScans(args.login, args.tserver)
-      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("getActiveScans", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getActiveCompactions(self, seqid, iprot, oprot):
-    args = getActiveCompactions_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getActiveCompactions_result()
-    try:
-      result.success = self._handler.getActiveCompactions(args.login, args.tserver)
-      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("getActiveCompactions", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getSiteConfiguration(self, seqid, iprot, oprot):
-    args = getSiteConfiguration_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getSiteConfiguration_result()
-    try:
-      result.success = self._handler.getSiteConfiguration(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("getSiteConfiguration", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getSystemConfiguration(self, seqid, iprot, oprot):
-    args = getSystemConfiguration_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getSystemConfiguration_result()
-    try:
-      result.success = self._handler.getSystemConfiguration(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("getSystemConfiguration", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getTabletServers(self, seqid, iprot, oprot):
-    args = getTabletServers_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getTabletServers_result()
-    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()
-
-  def process_removeProperty(self, seqid, iprot, oprot):
-    args = removeProperty_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = removeProperty_result()
-    try:
-      self._handler.removeProperty(args.login, 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 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()
-
-  def process_setProperty(self, seqid, iprot, oprot):
-    args = setProperty_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = setProperty_result()
-    try:
-      self._handler.setProperty(args.login, 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 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()
-
-  def process_testClassLoad(self, seqid, iprot, oprot):
-    args = testClassLoad_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = testClassLoad_result()
-    try:
-      result.success = self._handler.testClassLoad(args.login, 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 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()
-
-  def process_authenticateUser(self, seqid, iprot, oprot):
-    args = authenticateUser_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = authenticateUser_result()
-    try:
-      result.success = self._handler.authenticateUser(args.login, args.user, args.properties)
-      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("authenticateUser", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_changeUserAuthorizations(self, seqid, iprot, oprot):
-    args = changeUserAuthorizations_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = changeUserAuthorizations_result()
-    try:
-      self._handler.changeUserAuthorizations(args.login, args.user, args.authorizations)
-      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("changeUserAuthorizations", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_changeLocalUserPassword(self, seqid, iprot, oprot):
-    args = changeLocalUserPassword_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = changeLocalUserPassword_result()
-    try:
-      self._handler.changeLocalUserPassword(args.login, args.user, args.password)
-      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("changeLocalUserPassword", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_createLocalUser(self, seqid, iprot, oprot):
-    args = createLocalUser_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = createLocalUser_result()
-    try:
-      self._handler.createLocalUser(args.login, args.user, args.password)
-      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("createLocalUser", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_dropLocalUser(self, seqid, iprot, oprot):
-    args = dropLocalUser_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = dropLocalUser_result()
-    try:
-      self._handler.dropLocalUser(args.login, args.user)
-      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("dropLocalUser", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_getUserAuthorizations(self, seqid, iprot, oprot):
-    args = getUserAuthorizations_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getUserAuthorizations_result()
-    try:
-      result.success = self._handler.getUserAuthorizations(args.login, args.user)
-      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("getUserAuthorizations", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_grantSystemPermission(self, seqid, iprot, oprot):
-    args = grantSystemPermission_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = grantSystemPermission_result()
-    try:
-      self._handler.grantSystemPermission(args.login, args.user, 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("grantSystemPermission", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_grantTablePermission(self, seqid, iprot, oprot):
-    args = grantTablePermission_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = grantTablePermission_result()
-    try:
-      self._handler.grantTablePermission(args.login, args.user, args.table, 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 TableNotFoundException 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("grantTablePermission", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_hasSystemPermission(self, seqid, iprot, oprot):
-    args = hasSystemPermission_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = hasSystemPermission_result()
-    try:
-      result.success = self._handler.hasSystemPermission(args.login, args.user, 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("hasSystemPermission", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_hasTablePermission(self, seqid, iprot, oprot):
-    args = hasTablePermission_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = hasTablePermission_result()
-    try:
-      result.success = self._handler.hasTablePermission(args.login, args.user, args.table, 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 TableNotFoundException 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("hasTablePermission", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_listLocalUsers(self, seqid, iprot, oprot):
-    args = listLocalUsers_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = listLocalUsers_result()
-    try:
-      result.success = self._handler.listLocalUsers(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 TableNotFoundException 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("listLocalUsers", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_revokeSystemPermission(self, seqid, iprot, oprot):
-    args = revokeSystemPermission_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = revokeSystemPermission_result()
-    try:
-      self._handler.revokeSystemPermission(args.login, args.user, 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("revokeSystemPermission", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_revokeTablePermission(self, seqid, iprot, oprot):
-    args = revokeTablePermission_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = revokeTablePermission_result()
-    try:
-      self._handler.revokeTablePermission(args.login, args.user, args.table, 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 TableNotFoundException 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("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()
-
-  def process_createBatchScanner(self, seqid, iprot, oprot):
-    args = createBatchScanner_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = createBatchScanner_result()
-    try:
-      result.success = self._handler.createBatchScanner(args.login, args.tableName, args.options)
-      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 TableNotFoundException 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("createBatchScanner", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_createScanner(self, seqid, iprot, oprot):
-    args = createScanner_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = createScanner_result()
-    try:
-      result.success = self._handler.createScanner(args.login, args.tableName, args.options)
-      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 TableNotFoundException 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("createScanner", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_hasNext(self, seqid, iprot, oprot):
-    args = hasNext_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = hasNext_result()
-    try:
-      result.success = self._handler.hasNext(args.scanner)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except UnknownScanner as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    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()
-
-  def process_nextEntry(self, seqid, iprot, oprot):
-    args = nextEntry_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = nextEntry_result()
-    try:
-      result.success = self._handler.nextEntry(args.scanner)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except NoMoreEntriesException as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except UnknownScanner as ouch2:
-      msg_type = TMessageType.REPLY
-      result.ouch2 = ouch2
-    except AccumuloSecurityException 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("nextEntry", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_nextK(self, seqid, iprot, oprot):
-    args = nextK_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = nextK_result()
-    try:
-      result.success = self._handler.nextK(args.scanner, args.k)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except NoMoreEntriesException as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except UnknownScanner as ouch2:
-      msg_type = TMessageType.REPLY
-      result.ouch2 = ouch2
-    except AccumuloSecurityException 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("nextK", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_closeScanner(self, seqid, iprot, oprot):
-    args = closeScanner_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = closeScanner_result()
-    try:
-      self._handler.closeScanner(args.scanner)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except UnknownScanner as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    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()
-
-  def process_updateAndFlush(self, seqid, iprot, oprot):
-    args = updateAndFlush_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = updateAndFlush_result()
-    try:
-      self._handler.updateAndFlush(args.login, args.tableName, args.cells)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except AccumuloException as outch1:
-      msg_type = TMessageType.REPLY
-      result.outch1 = outch1
-    except AccumuloSecurityException as ouch2:
-      msg_type = TMessageType.REPLY
-      result.ouch2 = ouch2
-    except TableNotFoundException as ouch3:
-      msg_type = TMessageType.REPLY
-      result.ouch3 = ouch3
-    except MutationsRejectedException 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("updateAndFlush", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_createWriter(self, seqid, iprot, oprot):
-    args = createWriter_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = createWriter_result()
-    try:
-      result.success = self._handler.createWriter(args.login, args.tableName, args.opts)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except AccumuloException as outch1:
-      msg_type = TMessageType.REPLY
-      result.outch1 = outch1
-    except AccumuloSecurityException as ouch2:
-      msg_type = TMessageType.REPLY
-      result.ouch2 = ouch2
-    except TableNotFoundException 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("createWriter", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_update(self, seqid, iprot, oprot):
-    args = update_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    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()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = flush_result()
-    try:
-      self._handler.flush(args.writer)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except UnknownWriter as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except MutationsRejectedException 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("flush", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_closeWriter(self, seqid, iprot, oprot):
-    args = closeWriter_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = closeWriter_result()
-    try:
-      self._handler.closeWriter(args.writer)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except UnknownWriter as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except MutationsRejectedException 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("closeWriter", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_updateRowConditionally(self, seqid, iprot, oprot):
-    args = updateRowConditionally_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = updateRowConditionally_result()
-    try:
-      result.success = self._handler.updateRowConditionally(args.login, args.tableName, args.row, args.updates)
-      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 TableNotFoundException 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("updateRowConditionally", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_createConditionalWriter(self, seqid, iprot, oprot):
-    args = createConditionalWriter_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = createConditionalWriter_result()
-    try:
-      result.success = self._handler.createConditionalWriter(args.login, args.tableName, args.options)
-      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 TableNotFoundException 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("createConditionalWriter", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_updateRowsConditionally(self, seqid, iprot, oprot):
-    args = updateRowsConditionally_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = updateRowsConditionally_result()
-    try:
-      result.success = self._handler.updateRowsConditionally(args.conditionalWriter, args.updates)
-      msg_type = TMessageType.REPLY
-    except (TTransport.TTransportException, KeyboardInterrupt, SystemExit):
-      raise
-    except UnknownWriter as ouch1:
-      msg_type = TMessageType.REPLY
-      result.ouch1 = ouch1
-    except AccumuloException as ouch2:
-      msg_type = TMessageType.REPLY
-      result.ouch2 = ouch2
-    except AccumuloSecurityException 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("updateRowsConditionally", msg_type, seqid)
-    result.write(oprot)
-    oprot.writeMessageEnd()
-    oprot.trans.flush()
-
-  def process_closeConditionalWriter(self, seqid, iprot, oprot):
-    args = closeConditionalWriter_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = closeConditionalWriter_result()
-    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()
-
-  def process_getRowRange(self, seqid, iprot, oprot):
-    args = getRowRange_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getRowRange_result()
-    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()
-
-  def process_getFollowing(self, seqid, iprot, oprot):
-    args = getFollowing_args()
-    args.read(iprot)
-    iprot.readMessageEnd()
-    result = getFollowing_result()
-    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()
-
-
-# HELPER FUNCTIONS AND STRUCTURES
-
-class login_args:
-  """
-  Attributes:
-   - principal
-   - loginProperties
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'principal', None, None, ), # 1
-    (2, TType.MAP, 'loginProperties', (TType.STRING,None,TType.STRING,None), None, ), # 2
-  )
-
-  def __init__(self, principal=None, loginProperties=None,):
-    self.principal = principal
-    self.loginProperties = loginProperties
-
-  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.principal = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.MAP:
-          self.loginProperties = {}
-          (_ktype145, _vtype146, _size144 ) = iprot.readMapBegin()
-          for _i148 in xrange(_size144):
-            _key149 = iprot.readString()
-            _val150 = iprot.readString()
-            self.loginProperties[_key149] = _val150
-          iprot.readMapEnd()
-        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('login_args')
-    if self.principal is not None:
-      oprot.writeFieldBegin('principal', TType.STRING, 1)
-      oprot.writeString(self.principal)
-      oprot.writeFieldEnd()
-    if self.loginProperties is not None:
-      oprot.writeFieldBegin('loginProperties', TType.MAP, 2)
-      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.loginProperties))
-      for kiter151,viter152 in self.loginProperties.items():
-        oprot.writeString(kiter151)
-        oprot.writeString(viter152)
-      oprot.writeMapEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 login_result:
-  """
-  Attributes:
-   - success
-   - ouch2
-  """
-
-  thrift_spec = (
-    (0, TType.STRING, 'success', None, None, ), # 0
-    (1, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 1
-  )
-
-  def __init__(self, success=None, ouch2=None,):
-    self.success = success
-    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.STRING:
-          self.success = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 1:
-        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('login_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.STRING, 0)
-      oprot.writeString(self.success)
-      oprot.writeFieldEnd()
-    if self.ouch2 is not None:
-      oprot.writeFieldBegin('ouch2', TType.STRUCT, 1)
-      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.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 addConstraint_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - constraintClassName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'constraintClassName', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, constraintClassName=None,):
-    self.login = login
-    self.tableName = tableName
-    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.tableName = 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('addConstraint_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.tableName)
-    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 addConstraint_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('addConstraint_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 addSplits_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - splits
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.SET, 'splits', (TType.STRING,None), None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, splits=None,):
-    self.login = login
-    self.tableName = tableName
-    self.splits = splits
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.SET:
-          self.splits = set()
-          (_etype156, _size153) = iprot.readSetBegin()
-          for _i157 in xrange(_size153):
-            _elem158 = iprot.readString()
-            self.splits.add(_elem158)
-          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('addSplits_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.splits is not None:
-      oprot.writeFieldBegin('splits', TType.SET, 3)
-      oprot.writeSetBegin(TType.STRING, len(self.splits))
-      for iter159 in self.splits:
-        oprot.writeString(iter159)
-      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.tableName)
-    value = (value * 31) ^ hash(self.splits)
-    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 addSplits_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('addSplits_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 attachIterator_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - setting
-   - scopes
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', 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, tableName=None, setting=None, scopes=None,):
-    self.login = login
-    self.tableName = tableName
-    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.tableName = 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()
-          (_etype163, _size160) = iprot.readSetBegin()
-          for _i164 in xrange(_size160):
-            _elem165 = iprot.readI32()
-            self.scopes.add(_elem165)
-          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('attachIterator_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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 iter166 in self.scopes:
-        oprot.writeI32(iter166)
-      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.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()]
-    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 attachIterator_result:
-  """
-  Attributes:
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'ouch1', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (AccumuloException, AccumuloException.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch3', (TableNotFoundException, TableNotFoundException.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 = AccumuloSecurityException()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch2 = AccumuloException()
-          self.ouch2.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch3 = TableNotFoundException()
-          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('attachIterator_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 checkIteratorConflicts_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - setting
-   - scopes
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', 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, tableName=None, setting=None, scopes=None,):
-    self.login = login
-    self.tableName = tableName
-    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.tableName = 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()
-          (_etype170, _size167) = iprot.readSetBegin()
-          for _i171 in xrange(_size167):
-            _elem172 = iprot.readI32()
-            self.scopes.add(_elem172)
-          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('checkIteratorConflicts_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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 iter173 in self.scopes:
-        oprot.writeI32(iter173)
-      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.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()]
-    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 checkIteratorConflicts_result:
-  """
-  Attributes:
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'ouch1', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (AccumuloException, AccumuloException.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch3', (TableNotFoundException, TableNotFoundException.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 = AccumuloSecurityException()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch2 = AccumuloException()
-          self.ouch2.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch3 = TableNotFoundException()
-          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('checkIteratorConflicts_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 clearLocatorCache_args:
-  """
-  Attributes:
-   - login
-   - tableName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tableName=None,):
-    self.login = login
-    self.tableName = tableName
-
-  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.tableName = 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('clearLocatorCache_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.tableName)
-    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 clearLocatorCache_result:
-  """
-  Attributes:
-   - ouch1
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'ouch1', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ), # 1
-  )
-
-  def __init__(self, ouch1=None,):
-    self.ouch1 = ouch1
-
-  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 = TableNotFoundException()
-          self.ouch1.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('clearLocatorCache_result')
-    if self.ouch1 is not None:
-      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
-      self.ouch1.write(oprot)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 cloneTable_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - newTableName
-   - flush
-   - propertiesToSet
-   - propertiesToExclude
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'newTableName', None, None, ), # 3
-    (4, TType.BOOL, 'flush', None, None, ), # 4
-    (5, TType.MAP, 'propertiesToSet', (TType.STRING,None,TType.STRING,None), None, ), # 5
-    (6, TType.SET, 'propertiesToExclude', (TType.STRING,None), None, ), # 6
-  )
-
-  def __init__(self, login=None, tableName=None, newTableName=None, flush=None, propertiesToSet=None, propertiesToExclude=None,):
-    self.login = login
-    self.tableName = tableName
-    self.newTableName = newTableName
-    self.flush = flush
-    self.propertiesToSet = propertiesToSet
-    self.propertiesToExclude = propertiesToExclude
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.newTableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.BOOL:
-          self.flush = iprot.readBool()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.MAP:
-          self.propertiesToSet = {}
-          (_ktype175, _vtype176, _size174 ) = iprot.readMapBegin()
-          for _i178 in xrange(_size174):
-            _key179 = iprot.readString()
-            _val180 = iprot.readString()
-            self.propertiesToSet[_key179] = _val180
-          iprot.readMapEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 6:
-        if ftype == TType.SET:
-          self.propertiesToExclude = set()
-          (_etype184, _size181) = iprot.readSetBegin()
-          for _i185 in xrange(_size181):
-            _elem186 = iprot.readString()
-            self.propertiesToExclude.add(_elem186)
-          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('cloneTable_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.newTableName is not None:
-      oprot.writeFieldBegin('newTableName', TType.STRING, 3)
-      oprot.writeString(self.newTableName)
-      oprot.writeFieldEnd()
-    if self.flush is not None:
-      oprot.writeFieldBegin('flush', TType.BOOL, 4)
-      oprot.writeBool(self.flush)
-      oprot.writeFieldEnd()
-    if self.propertiesToSet is not None:
-      oprot.writeFieldBegin('propertiesToSet', TType.MAP, 5)
-      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.propertiesToSet))
-      for kiter187,viter188 in self.propertiesToSet.items():
-        oprot.writeString(kiter187)
-        oprot.writeString(viter188)
-      oprot.writeMapEnd()
-      oprot.writeFieldEnd()
-    if self.propertiesToExclude is not None:
-      oprot.writeFieldBegin('propertiesToExclude', TType.SET, 6)
-      oprot.writeSetBegin(TType.STRING, len(self.propertiesToExclude))
-      for iter189 in self.propertiesToExclude:
-        oprot.writeString(iter189)
-      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.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()]
-    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 cloneTable_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', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ), # 3
-    (4, TType.STRUCT, 'ouch4', (TableExistsException, TableExistsException.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 = TableNotFoundException()
-          self.ouch3.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRUCT:
-          self.ouch4 = TableExistsException()
-          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('cloneTable_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 compactTable_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - startRow
-   - endRow
-   - iterators
-   - flush
-   - wait
-   - compactionStrategy
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'startRow', None, None, ), # 3
-    (4, TType.STRING, 'endRow', None, None, ), # 4
-    (5, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 5
-    (6, TType.BOOL, 'flush', None, None, ), # 6
-    (7, TType.BOOL, 'wait', None, None, ), # 7
-    (8, TType.STRUCT, 'compactionStrategy', (CompactionStrategyConfig, CompactionStrategyConfig.thrift_spec), None, ), # 8
-  )
-
-  def __init__(self, login=None, tableName=None, startRow=None, endRow=None, iterators=None, flush=None, wait=None, compactionStrategy=None,):
-    self.login = login
-    self.tableName = tableName
-    self.startRow = startRow
-    self.endRow = endRow
-    self.iterators = iterators
-    self.flush = flush
-    self.wait = wait
-    self.compactionStrategy = compactionStrategy
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.startRow = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRING:
-          self.endRow = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.LIST:
-          self.iterators = []
-          (_etype193, _size190) = iprot.readListBegin()
-          for _i194 in xrange(_size190):
-            _elem195 = IteratorSetting()
-            _elem195.read(iprot)
-            self.iterators.append(_elem195)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 6:
-        if ftype == TType.BOOL:
-          self.flush = iprot.readBool()
-        else:
-          iprot.skip(ftype)
-      elif fid == 7:
-        if ftype == TType.BOOL:
-          self.wait = iprot.readBool()
-        else:
-          iprot.skip(ftype)
-      elif fid == 8:
-        if ftype == TType.STRUCT:
-          self.compactionStrategy = CompactionStrategyConfig()
-          self.compactionStrategy.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('compactTable_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.startRow is not None:
-      oprot.writeFieldBegin('startRow', TType.STRING, 3)
-      oprot.writeString(self.startRow)
-      oprot.writeFieldEnd()
-    if self.endRow is not None:
-      oprot.writeFieldBegin('endRow', TType.STRING, 4)
-      oprot.writeString(self.endRow)
-      oprot.writeFieldEnd()
-    if self.iterators is not None:
-      oprot.writeFieldBegin('iterators', TType.LIST, 5)
-      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
-      for iter196 in self.iterators:
-        iter196.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.flush is not None:
-      oprot.writeFieldBegin('flush', TType.BOOL, 6)
-      oprot.writeBool(self.flush)
-      oprot.writeFieldEnd()
-    if self.wait is not None:
-      oprot.writeFieldBegin('wait', TType.BOOL, 7)
-      oprot.writeBool(self.wait)
-      oprot.writeFieldEnd()
-    if self.compactionStrategy is not None:
-      oprot.writeFieldBegin('compactionStrategy', TType.STRUCT, 8)
-      self.compactionStrategy.write(oprot)
-      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.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()]
-    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 compactTable_result:
-  """
-  Attributes:
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'ouch1', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch3', (AccumuloException, AccumuloException.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 = AccumuloSecurityException()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch2 = TableNotFoundException()
-          self.ouch2.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch3 = AccumuloException()
-          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('compactTable_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 cancelCompaction_args:
-  """
-  Attributes:
-   - login
-   - tableName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tableName=None,):
-    self.login = login
-    self.tableName = tableName
-
-  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.tableName = 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('cancelCompaction_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.tableName)
-    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 cancelCompaction_result:
-  """
-  Attributes:
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'ouch1', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch3', (AccumuloException, AccumuloException.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 = AccumuloSecurityException()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch2 = TableNotFoundException()
-          self.ouch2.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch3 = AccumuloException()
-          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('cancelCompaction_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 createTable_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - versioningIter
-   - type
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.BOOL, 'versioningIter', None, None, ), # 3
-    (4, TType.I32, 'type', None, None, ), # 4
-  )
-
-  def __init__(self, login=None, tableName=None, versioningIter=None, type=None,):
-    self.login = login
-    self.tableName = tableName
-    self.versioningIter = versioningIter
-    self.type = type
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.BOOL:
-          self.versioningIter = iprot.readBool()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.I32:
-          self.type = 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('createTable_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.versioningIter is not None:
-      oprot.writeFieldBegin('versioningIter', TType.BOOL, 3)
-      oprot.writeBool(self.versioningIter)
-      oprot.writeFieldEnd()
-    if self.type is not None:
-      oprot.writeFieldBegin('type', TType.I32, 4)
-      oprot.writeI32(self.type)
-      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.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()]
-    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 createTable_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', (TableExistsException, TableExistsException.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 = TableExistsException()
-          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('createTable_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 deleteTable_args:
-  """
-  Attributes:
-   - login
-   - tableName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tableName=None,):
-    self.login = login
-    self.tableName = tableName
-
-  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.tableName = 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('deleteTable_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.tableName)
-    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 deleteTable_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('deleteTable_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 deleteRows_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - startRow
-   - endRow
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'startRow', None, None, ), # 3
-    (4, TType.STRING, 'endRow', None, None, ), # 4
-  )
-
-  def __init__(self, login=None, tableName=None, startRow=None, endRow=None,):
-    self.login = login
-    self.tableName = tableName
-    self.startRow = startRow
-    self.endRow = endRow
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.startRow = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRING:
-          self.endRow = 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('deleteRows_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.startRow is not None:
-      oprot.writeFieldBegin('startRow', TType.STRING, 3)
-      oprot.writeString(self.startRow)
-      oprot.writeFieldEnd()
-    if self.endRow is not None:
-      oprot.writeFieldBegin('endRow', TType.STRING, 4)
-      oprot.writeString(self.endRow)
-      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.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()]
-    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 deleteRows_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('deleteRows_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 exportTable_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - exportDir
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'exportDir', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, exportDir=None,):
-    self.login = login
-    self.tableName = tableName
-    self.exportDir = exportDir
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.exportDir = 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('exportTable_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.exportDir is not None:
-      oprot.writeFieldBegin('exportDir', TType.STRING, 3)
-      oprot.writeString(self.exportDir)
-      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.tableName)
-    value = (value * 31) ^ hash(self.exportDir)
-    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 exportTable_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('exportTable_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 flushTable_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - startRow
-   - endRow
-   - wait
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'startRow', None, None, ), # 3
-    (4, TType.STRING, 'endRow', None, None, ), # 4
-    (5, TType.BOOL, 'wait', None, None, ), # 5
-  )
-
-  def __init__(self, login=None, tableName=None, startRow=None, endRow=None, wait=None,):
-    self.login = login
-    self.tableName = tableName
-    self.startRow = startRow
-    self.endRow = endRow
-    self.wait = wait
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.startRow = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRING:
-          self.endRow = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.BOOL:
-          self.wait = iprot.readBool()
-        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('flushTable_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.startRow is not None:
-      oprot.writeFieldBegin('startRow', TType.STRING, 3)
-      oprot.writeString(self.startRow)
-      oprot.writeFieldEnd()
-    if self.endRow is not None:
-      oprot.writeFieldBegin('endRow', TType.STRING, 4)
-      oprot.writeString(self.endRow)
-      oprot.writeFieldEnd()
-    if self.wait is not None:
-      oprot.writeFieldBegin('wait', TType.BOOL, 5)
-      oprot.writeBool(self.wait)
-      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.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()]
-    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 flushTable_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('flushTable_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 getDiskUsage_args:
-  """
-  Attributes:
-   - login
-   - tables
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.SET, 'tables', (TType.STRING,None), None, ), # 2
-  )
-
-  def __init__(self, login=None, tables=None,):
-    self.login = login
-    self.tables = tables
-
-  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.SET:
-          self.tables = set()
-          (_etype200, _size197) = iprot.readSetBegin()
-          for _i201 in xrange(_size197):
-            _elem202 = iprot.readString()
-            self.tables.add(_elem202)
-          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('getDiskUsage_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tables is not None:
-      oprot.writeFieldBegin('tables', TType.SET, 2)
-      oprot.writeSetBegin(TType.STRING, len(self.tables))
-      for iter203 in self.tables:
-        oprot.writeString(iter203)
-      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.tables)
-    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 getDiskUsage_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.LIST, 'success', (TType.STRUCT,(DiskUsage, DiskUsage.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', (TableNotFoundException, TableNotFoundException.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.LIST:
-          self.success = []
-          (_etype207, _size204) = iprot.readListBegin()
-          for _i208 in xrange(_size204):
-            _elem209 = DiskUsage()
-            _elem209.read(iprot)
-            self.success.append(_elem209)
-          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)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch3 = TableNotFoundException()
-          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('getDiskUsage_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.LIST, 0)
-      oprot.writeListBegin(TType.STRUCT, len(self.success))
-      for iter210 in self.success:
-        iter210.write(oprot)
-      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()
-    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 getLocalityGroups_args:
-  """
-  Attributes:
-   - login
-   - tableName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tableName=None,):
-    self.login = login
-    self.tableName = tableName
-
-  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.tableName = 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('getLocalityGroups_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.tableName)
-    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 getLocalityGroups_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.MAP, 'success', (TType.STRING,None,TType.SET,(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', (TableNotFoundException, TableNotFoundException.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 = {}
-          (_ktype212, _vtype213, _size211 ) = iprot.readMapBegin()
-          for _i215 in xrange(_size211):
-            _key216 = iprot.readString()
-            _val217 = set()
-            (_etype221, _size218) = iprot.readSetBegin()
-            for _i222 in xrange(_size218):
-              _elem223 = iprot.readString()
-              _val217.add(_elem223)
-            iprot.readSetEnd()
-            self.success[_key216] = _val217
-          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 = TableNotFoundException()
-          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('getLocalityGroups_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.MAP, 0)
-      oprot.writeMapBegin(TType.STRING, TType.SET, len(self.success))
-      for kiter224,viter225 in self.success.items():
-        oprot.writeString(kiter224)
-        oprot.writeSetBegin(TType.STRING, len(viter225))
-        for iter226 in viter225:
-          oprot.writeString(iter226)
-        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 getIteratorSetting_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - iteratorName
-   - scope
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'iteratorName', None, None, ), # 3
-    (4, TType.I32, 'scope', None, None, ), # 4
-  )
-
-  def __init__(self, login=None, tableName=None, iteratorName=None, scope=None,):
-    self.login = login
-    self.tableName = tableName
-    self.iteratorName = iteratorName
-    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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.iteratorName = 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('getIteratorSetting_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.iteratorName is not None:
-      oprot.writeFieldBegin('iteratorName', TType.STRING, 3)
-      oprot.writeString(self.iteratorName)
-      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.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()]
-    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 getIteratorSetting_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('getIteratorSetting_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 getMaxRow_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - auths
-   - startRow
-   - startInclusive
-   - endRow
-   - endInclusive
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.SET, 'auths', (TType.STRING,None), None, ), # 3
-    (4, TType.STRING, 'startRow', None, None, ), # 4
-    (5, TType.BOOL, 'startInclusive', None, None, ), # 5
-    (6, TType.STRING, 'endRow', None, None, ), # 6
-    (7, TType.BOOL, 'endInclusive', None, None, ), # 7
-  )
-
-  def __init__(self, login=None, tableName=None, auths=None, startRow=None, startInclusive=None, endRow=None, endInclusive=None,):
-    self.login = login
-    self.tableName = tableName
-    self.auths = auths
-    self.startRow = startRow
-    self.startInclusive = startInclusive
-    self.endRow = endRow
-    self.endInclusive = endInclusive
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.SET:
-          self.auths = set()
-          (_etype230, _size227) = iprot.readSetBegin()
-          for _i231 in xrange(_size227):
-            _elem232 = iprot.readString()
-            self.auths.add(_elem232)
-          iprot.readSetEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRING:
-          self.startRow = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.BOOL:
-          self.startInclusive = iprot.readBool()
-        else:
-          iprot.skip(ftype)
-      elif fid == 6:
-        if ftype == TType.STRING:
-          self.endRow = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 7:
-        if ftype == TType.BOOL:
-          self.endInclusive = iprot.readBool()
-        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('getMaxRow_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.auths is not None:
-      oprot.writeFieldBegin('auths', TType.SET, 3)
-      oprot.writeSetBegin(TType.STRING, len(self.auths))
-      for iter233 in self.auths:
-        oprot.writeString(iter233)
-      oprot.writeSetEnd()
-      oprot.writeFieldEnd()
-    if self.startRow is not None:
-      oprot.writeFieldBegin('startRow', TType.STRING, 4)
-      oprot.writeString(self.startRow)
-      oprot.writeFieldEnd()
-    if self.startInclusive is not None:
-      oprot.writeFieldBegin('startInclusive', TType.BOOL, 5)
-      oprot.writeBool(self.startInclusive)
-      oprot.writeFieldEnd()
-    if self.endRow is not None:
-      oprot.writeFieldBegin('endRow', TType.STRING, 6)
-      oprot.writeString(self.endRow)
-      oprot.writeFieldEnd()
-    if self.endInclusive is not None:
-      oprot.writeFieldBegin('endInclusive', TType.BOOL, 7)
-      oprot.writeBool(self.endInclusive)
-      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.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()]
-    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 getMaxRow_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.STRING, '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', (TableNotFoundException, TableNotFoundException.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.STRING:
-          self.success = iprot.readString()
-        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 = TableNotFoundException()
-          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('getMaxRow_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.STRING, 0)
-      oprot.writeString(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 getTableProperties_args:
-  """
-  Attributes:
-   - login
-   - tableName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tableName=None,):
-    self.login = login
-    self.tableName = tableName
-
-  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.tableName = 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('getTableProperties_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.tableName)
-    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 getTableProperties_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', (TableNotFoundException, TableNotFoundException.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 = {}
-          (_ktype235, _vtype236, _size234 ) = iprot.readMapBegin()
-          for _i238 in xrange(_size234):
-            _key239 = iprot.readString()
-            _val240 = iprot.readString()
-            self.success[_key239] = _val240
-          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 = TableNotFoundException()
-          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('getTableProperties_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.MAP, 0)
-      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
-      for kiter241,viter242 in self.success.items():
-        oprot.writeString(kiter241)
-        oprot.writeString(viter242)
-      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 importDirectory_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - importDir
-   - failureDir
-   - setTime
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'importDir', None, None, ), # 3
-    (4, TType.STRING, 'failureDir', None, None, ), # 4
-    (5, TType.BOOL, 'setTime', None, None, ), # 5
-  )
-
-  def __init__(self, login=None, tableName=None, importDir=None, failureDir=None, setTime=None,):
-    self.login = login
-    self.tableName = tableName
-    self.importDir = importDir
-    self.failureDir = failureDir
-    self.setTime = setTime
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.importDir = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRING:
-          self.failureDir = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.BOOL:
-          self.setTime = iprot.readBool()
-        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('importDirectory_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.importDir is not None:
-      oprot.writeFieldBegin('importDir', TType.STRING, 3)
-      oprot.writeString(self.importDir)
-      oprot.writeFieldEnd()
-    if self.failureDir is not None:
-      oprot.writeFieldBegin('failureDir', TType.STRING, 4)
-      oprot.writeString(self.failureDir)
-      oprot.writeFieldEnd()
-    if self.setTime is not None:
-      oprot.writeFieldBegin('setTime', TType.BOOL, 5)
-      oprot.writeBool(self.setTime)
-      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.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()]
-    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 importDirectory_result:
-  """
-  Attributes:
-   - ouch1
-   - ouch3
-   - ouch4
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'ouch1', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch3', (AccumuloException, AccumuloException.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch4', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 3
-  )
-
-  def __init__(self, ouch1=None, ouch3=None, ouch4=None,):
-    self.ouch1 = ouch1
-    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 = TableNotFoundException()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch3 = AccumuloException()
-          self.ouch3.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch4 = AccumuloSecurityException()
-          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('importDirectory_result')
-    if self.ouch1 is not None:
-      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
-      self.ouch1.write(oprot)
-      oprot.writeFieldEnd()
-    if self.ouch3 is not None:
-      oprot.writeFieldBegin('ouch3', TType.STRUCT, 2)
-      self.ouch3.write(oprot)
-      oprot.writeFieldEnd()
-    if self.ouch4 is not None:
-      oprot.writeFieldBegin('ouch4', TType.STRUCT, 3)
-      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.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 importTable_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - importDir
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'importDir', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, importDir=None,):
-    self.login = login
-    self.tableName = tableName
-    self.importDir = importDir
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.importDir = 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('importTable_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.importDir is not None:
-      oprot.writeFieldBegin('importDir', TType.STRING, 3)
-      oprot.writeString(self.importDir)
-      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.tableName)
-    value = (value * 31) ^ hash(self.importDir)
-    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 importTable_result:
-  """
-  Attributes:
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'ouch1', (TableExistsException, TableExistsException.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (AccumuloException, AccumuloException.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch3', (AccumuloSecurityException, AccumuloSecurityException.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 = TableExistsException()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch2 = AccumuloException()
-          self.ouch2.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch3 = AccumuloSecurityException()
-          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('importTable_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 listSplits_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - maxSplits
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.I32, 'maxSplits', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, maxSplits=None,):
-    self.login = login
-    self.tableName = tableName
-    self.maxSplits = maxSplits
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.I32:
-          self.maxSplits = 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('listSplits_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.maxSplits is not None:
-      oprot.writeFieldBegin('maxSplits', TType.I32, 3)
-      oprot.writeI32(self.maxSplits)
-      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.tableName)
-    value = (value * 31) ^ hash(self.maxSplits)
-    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 listSplits_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  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
-    (3, TType.STRUCT, 'ouch3', (TableNotFoundException, TableNotFoundException.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.LIST:
-          self.success = []
-          (_etype246, _size243) = iprot.readListBegin()
-          for _i247 in xrange(_size243):
-            _elem248 = iprot.readString()
-            self.success.append(_elem248)
-          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)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch3 = TableNotFoundException()
-          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('listSplits_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.LIST, 0)
-      oprot.writeListBegin(TType.STRING, len(self.success))
-      for iter249 in self.success:
-        oprot.writeString(iter249)
-      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()
-    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 listTables_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('listTables_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 listTables_result:
-  """
-  Attributes:
-   - success
-  """
-
-  thrift_spec = (
-    (0, TType.SET, 'success', (TType.STRING,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.SET:
-          self.success = set()
-          (_etype253, _size250) = iprot.readSetBegin()
-          for _i254 in xrange(_size250):
-            _elem255 = iprot.readString()
-            self.success.add(_elem255)
-          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('listTables_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.SET, 0)
-      oprot.writeSetBegin(TType.STRING, len(self.success))
-      for iter256 in self.success:
-        oprot.writeString(iter256)
-      oprot.writeSetEnd()
-      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 listIterators_args:
-  """
-  Attributes:
-   - login
-   - tableName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tableName=None,):
-    self.login = login
-    self.tableName = tableName
-
-  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.tableName = 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('listIterators_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.tableName)
-    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 listIterators_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', (TableNotFoundException, TableNotFoundException.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 = {}
-          (_ktype258, _vtype259, _size257 ) = iprot.readMapBegin()
-          for _i261 in xrange(_size257):
-            _key262 = iprot.readString()
-            _val263 = set()
-            (_etype267, _size264) = iprot.readSetBegin()
-            for _i268 in xrange(_size264):
-              _elem269 = iprot.readI32()
-              _val263.add(_elem269)
-            iprot.readSetEnd()
-            self.success[_key262] = _val263
-          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 = TableNotFoundException()
-          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('listIterators_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.MAP, 0)
-      oprot.writeMapBegin(TType.STRING, TType.SET, len(self.success))
-      for kiter270,viter271 in self.success.items():
-        oprot.writeString(kiter270)
-        oprot.writeSetBegin(TType.I32, len(viter271))
-        for iter272 in viter271:
-          oprot.writeI32(iter272)
-        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 listConstraints_args:
-  """
-  Attributes:
-   - login
-   - tableName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tableName=None,):
-    self.login = login
-    self.tableName = tableName
-
-  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.tableName = 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('listConstraints_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.tableName)
-    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 listConstraints_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', (TableNotFoundException, TableNotFoundException.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 = {}
-          (_ktype274, _vtype275, _size273 ) = iprot.readMapBegin()
-          for _i277 in xrange(_size273):
-            _key278 = iprot.readString()
-            _val279 = iprot.readI32()
-            self.success[_key278] = _val279
-          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 = TableNotFoundException()
-          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('listConstraints_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.MAP, 0)
-      oprot.writeMapBegin(TType.STRING, TType.I32, len(self.success))
-      for kiter280,viter281 in self.success.items():
-        oprot.writeString(kiter280)
-        oprot.writeI32(viter281)
-      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 mergeTablets_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - startRow
-   - endRow
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'startRow', None, None, ), # 3
-    (4, TType.STRING, 'endRow', None, None, ), # 4
-  )
-
-  def __init__(self, login=None, tableName=None, startRow=None, endRow=None,):
-    self.login = login
-    self.tableName = tableName
-    self.startRow = startRow
-    self.endRow = endRow
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.startRow = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRING:
-          self.endRow = 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('mergeTablets_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.startRow is not None:
-      oprot.writeFieldBegin('startRow', TType.STRING, 3)
-      oprot.writeString(self.startRow)
-      oprot.writeFieldEnd()
-    if self.endRow is not None:
-      oprot.writeFieldBegin('endRow', TType.STRING, 4)
-      oprot.writeString(self.endRow)
-      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.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()]
-    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 mergeTablets_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('mergeTablets_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 offlineTable_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - wait
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.BOOL, 'wait', None, False, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, wait=thrift_spec[3][4],):
-    self.login = login
-    self.tableName = tableName
-    self.wait = wait
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.BOOL:
-          self.wait = iprot.readBool()
-        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('offlineTable_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.wait is not None:
-      oprot.writeFieldBegin('wait', TType.BOOL, 3)
-      oprot.writeBool(self.wait)
-      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.tableName)
-    value = (value * 31) ^ hash(self.wait)
-    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 offlineTable_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('offlineTable_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 onlineTable_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - wait
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.BOOL, 'wait', None, False, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, wait=thrift_spec[3][4],):
-    self.login = login
-    self.tableName = tableName
-    self.wait = wait
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.BOOL:
-          self.wait = iprot.readBool()
-        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('onlineTable_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.wait is not None:
-      oprot.writeFieldBegin('wait', TType.BOOL, 3)
-      oprot.writeBool(self.wait)
-      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.tableName)
-    value = (value * 31) ^ hash(self.wait)
-    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 onlineTable_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('onlineTable_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 removeConstraint_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - constraint
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.I32, 'constraint', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, constraint=None,):
-    self.login = login
-    self.tableName = tableName
-    self.constraint = constraint
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.I32:
-          self.constraint = 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('removeConstraint_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.constraint is not None:
-      oprot.writeFieldBegin('constraint', TType.I32, 3)
-      oprot.writeI32(self.constraint)
-      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.tableName)
-    value = (value * 31) ^ hash(self.constraint)
-    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 removeConstraint_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('removeConstraint_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 removeIterator_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - iterName
-   - scopes
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'iterName', None, None, ), # 3
-    (4, TType.SET, 'scopes', (TType.I32,None), None, ), # 4
-  )
-
-  def __init__(self, login=None, tableName=None, iterName=None, scopes=None,):
-    self.login = login
-    self.tableName = tableName
-    self.iterName = iterName
-    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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.iterName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.SET:
-          self.scopes = set()
-          (_etype285, _size282) = iprot.readSetBegin()
-          for _i286 in xrange(_size282):
-            _elem287 = iprot.readI32()
-            self.scopes.add(_elem287)
-          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('removeIterator_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.iterName is not None:
-      oprot.writeFieldBegin('iterName', TType.STRING, 3)
-      oprot.writeString(self.iterName)
-      oprot.writeFieldEnd()
-    if self.scopes is not None:
-      oprot.writeFieldBegin('scopes', TType.SET, 4)
-      oprot.writeSetBegin(TType.I32, len(self.scopes))
-      for iter288 in self.scopes:
-        oprot.writeI32(iter288)
-      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.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()]
-    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 removeIterator_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('removeIterator_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 removeTableProperty_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - property
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'property', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, property=None,):
-    self.login = login
-    self.tableName = tableName
-    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.tableName = 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('removeTableProperty_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.tableName)
-    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 removeTableProperty_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('removeTableProperty_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 renameTable_args:
-  """
-  Attributes:
-   - login
-   - oldTableName
-   - newTableName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'oldTableName', None, None, ), # 2
-    (3, TType.STRING, 'newTableName', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, oldTableName=None, newTableName=None,):
-    self.login = login
-    self.oldTableName = oldTableName
-    self.newTableName = newTableName
-
-  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.oldTableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.newTableName = 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('renameTable_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.oldTableName is not None:
-      oprot.writeFieldBegin('oldTableName', TType.STRING, 2)
-      oprot.writeString(self.oldTableName)
-      oprot.writeFieldEnd()
-    if self.newTableName is not None:
-      oprot.writeFieldBegin('newTableName', TType.STRING, 3)
-      oprot.writeString(self.newTableName)
-      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.oldTableName)
-    value = (value * 31) ^ hash(self.newTableName)
-    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 renameTable_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', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ), # 3
-    (4, TType.STRUCT, 'ouch4', (TableExistsException, TableExistsException.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 = TableNotFoundException()
-          self.ouch3.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRUCT:
-          self.ouch4 = TableExistsException()
-          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('renameTable_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 setLocalityGroups_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - groups
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.MAP, 'groups', (TType.STRING,None,TType.SET,(TType.STRING,None)), None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, groups=None,):
-    self.login = login
-    self.tableName = tableName
-    self.groups = groups
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.MAP:
-          self.groups = {}
-          (_ktype290, _vtype291, _size289 ) = iprot.readMapBegin()
-          for _i293 in xrange(_size289):
-            _key294 = iprot.readString()
-            _val295 = set()
-            (_etype299, _size296) = iprot.readSetBegin()
-            for _i300 in xrange(_size296):
-              _elem301 = iprot.readString()
-              _val295.add(_elem301)
-            iprot.readSetEnd()
-            self.groups[_key294] = _val295
-          iprot.readMapEnd()
-        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('setLocalityGroups_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.groups is not None:
-      oprot.writeFieldBegin('groups', TType.MAP, 3)
-      oprot.writeMapBegin(TType.STRING, TType.SET, len(self.groups))
-      for kiter302,viter303 in self.groups.items():
-        oprot.writeString(kiter302)
-        oprot.writeSetBegin(TType.STRING, len(viter303))
-        for iter304 in viter303:
-          oprot.writeString(iter304)
-        oprot.writeSetEnd()
-      oprot.writeMapEnd()
-      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.tableName)
-    value = (value * 31) ^ hash(self.groups)
-    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 setLocalityGroups_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('setLocalityGroups_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 setTableProperty_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - property
-   - value
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'property', None, None, ), # 3
-    (4, TType.STRING, 'value', None, None, ), # 4
-  )
-
-  def __init__(self, login=None, tableName=None, property=None, value=None,):
-    self.login = login
-    self.tableName = tableName
-    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.tableName = 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('setTableProperty_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.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()]
-    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 setTableProperty_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('setTableProperty_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 splitRangeByTablets_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - range
-   - maxSplits
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRUCT, 'range', (Range, Range.thrift_spec), None, ), # 3
-    (4, TType.I32, 'maxSplits', None, None, ), # 4
-  )
-
-  def __init__(self, login=None, tableName=None, range=None, maxSplits=None,):
-    self.login = login
-    self.tableName = tableName
-    self.range = range
-    self.maxSplits = maxSplits
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.range = Range()
-          self.range.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.I32:
-          self.maxSplits = 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('splitRangeByTablets_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.range is not None:
-      oprot.writeFieldBegin('range', TType.STRUCT, 3)
-      self.range.write(oprot)
-      oprot.writeFieldEnd()
-    if self.maxSplits is not None:
-      oprot.writeFieldBegin('maxSplits', TType.I32, 4)
-      oprot.writeI32(self.maxSplits)
-      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.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()]
-    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 splitRangeByTablets_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.SET, 'success', (TType.STRUCT,(Range, Range.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', (TableNotFoundException, TableNotFoundException.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.SET:
-          self.success = set()
-          (_etype308, _size305) = iprot.readSetBegin()
-          for _i309 in xrange(_size305):
-            _elem310 = Range()
-            _elem310.read(iprot)
-            self.success.add(_elem310)
-          iprot.readSetEnd()
-        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 = TableNotFoundException()
-          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('splitRangeByTablets_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.SET, 0)
-      oprot.writeSetBegin(TType.STRUCT, len(self.success))
-      for iter311 in self.success:
-        iter311.write(oprot)
-      oprot.writeSetEnd()
-      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 tableExists_args:
-  """
-  Attributes:
-   - login
-   - tableName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tableName=None,):
-    self.login = login
-    self.tableName = tableName
-
-  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.tableName = 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('tableExists_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.tableName)
-    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 tableExists_result:
-  """
-  Attributes:
-   - success
-  """
-
-  thrift_spec = (
-    (0, TType.BOOL, '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.BOOL:
-          self.success = iprot.readBool()
-        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('tableExists_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.BOOL, 0)
-      oprot.writeBool(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 tableIdMap_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('tableIdMap_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 tableIdMap_result:
-  """
-  Attributes:
-   - success
-  """
-
-  thrift_spec = (
-    (0, TType.MAP, 'success', (TType.STRING,None,TType.STRING,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.MAP:
-          self.success = {}
-          (_ktype313, _vtype314, _size312 ) = iprot.readMapBegin()
-          for _i316 in xrange(_size312):
-            _key317 = iprot.readString()
-            _val318 = iprot.readString()
-            self.success[_key317] = _val318
-          iprot.readMapEnd()
-        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('tableIdMap_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.MAP, 0)
-      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
-      for kiter319,viter320 in self.success.items():
-        oprot.writeString(kiter319)
-        oprot.writeString(viter320)
-      oprot.writeMapEnd()
-      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 testTableClassLoad_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - className
-   - asTypeName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'className', None, None, ), # 3
-    (4, TType.STRING, 'asTypeName', None, None, ), # 4
-  )
-
-  def __init__(self, login=None, tableName=None, className=None, asTypeName=None,):
-    self.login = login
-    self.tableName = tableName
-    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.tableName = 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('testTableClassLoad_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      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.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()]
-    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 testTableClassLoad_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('testTableClassLoad_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()]
-    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 pingTabletServer_args:
-  """
-  Attributes:
-   - login
-   - tserver
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tserver', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tserver=None,):
-    self.login = login
-    self.tserver = tserver
-
-  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.tserver = 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('pingTabletServer_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tserver is not None:
-      oprot.writeFieldBegin('tserver', TType.STRING, 2)
-      oprot.writeString(self.tserver)
-      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.tserver)
-    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 pingTabletServer_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('pingTabletServer_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 getActiveScans_args:
-  """
-  Attributes:
-   - login
-   - tserver
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tserver', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tserver=None,):
-    self.login = login
-    self.tserver = tserver
-
-  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.tserver = 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('getActiveScans_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tserver is not None:
-      oprot.writeFieldBegin('tserver', TType.STRING, 2)
-      oprot.writeString(self.tserver)
-      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.tserver)
-    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 getActiveScans_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-  """
-
-  thrift_spec = (
-    (0, TType.LIST, 'success', (TType.STRUCT,(ActiveScan, ActiveScan.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, 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 = []
-          (_etype324, _size321) = iprot.readListBegin()
-          for _i325 in xrange(_size321):
-            _elem326 = ActiveScan()
-            _elem326.read(iprot)
-            self.success.append(_elem326)
-          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('getActiveScans_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.LIST, 0)
-      oprot.writeListBegin(TType.STRUCT, len(self.success))
-      for iter327 in self.success:
-        iter327.write(oprot)
-      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 getActiveCompactions_args:
-  """
-  Attributes:
-   - login
-   - tserver
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tserver', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, tserver=None,):
-    self.login = login
-    self.tserver = tserver
-
-  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.tserver = 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('getActiveCompactions_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tserver is not None:
-      oprot.writeFieldBegin('tserver', TType.STRING, 2)
-      oprot.writeString(self.tserver)
-      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.tserver)
-    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 getActiveCompactions_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-  """
-
-  thrift_spec = (
-    (0, TType.LIST, 'success', (TType.STRUCT,(ActiveCompaction, ActiveCompaction.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, 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 = []
-          (_etype331, _size328) = iprot.readListBegin()
-          for _i332 in xrange(_size328):
-            _elem333 = ActiveCompaction()
-            _elem333.read(iprot)
-            self.success.append(_elem333)
-          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('getActiveCompactions_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.LIST, 0)
-      oprot.writeListBegin(TType.STRUCT, len(self.success))
-      for iter334 in self.success:
-        iter334.write(oprot)
-      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 getSiteConfiguration_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('getSiteConfiguration_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 getSiteConfiguration_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 = {}
-          (_ktype336, _vtype337, _size335 ) = iprot.readMapBegin()
-          for _i339 in xrange(_size335):
-            _key340 = iprot.readString()
-            _val341 = iprot.readString()
-            self.success[_key340] = _val341
-          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('getSiteConfiguration_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.MAP, 0)
-      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
-      for kiter342,viter343 in self.success.items():
-        oprot.writeString(kiter342)
-        oprot.writeString(viter343)
-      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 getSystemConfiguration_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('getSystemConfiguration_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 getSystemConfiguration_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 = {}
-          (_ktype345, _vtype346, _size344 ) = iprot.readMapBegin()
-          for _i348 in xrange(_size344):
-            _key349 = iprot.readString()
-            _val350 = iprot.readString()
-            self.success[_key349] = _val350
-          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('getSystemConfiguration_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.MAP, 0)
-      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.success))
-      for kiter351,viter352 in self.success.items():
-        oprot.writeString(kiter351)
-        oprot.writeString(viter352)
-      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 getTabletServers_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('getTabletServers_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 getTabletServers_result:
-  """
-  Attributes:
-   - success
-  """
-
-  thrift_spec = (
-    (0, TType.LIST, 'success', (TType.STRING,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.LIST:
-          self.success = []
-          (_etype356, _size353) = iprot.readListBegin()
-          for _i357 in xrange(_size353):
-            _elem358 = iprot.readString()
-            self.success.append(_elem358)
-          iprot.readListEnd()
-        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('getTabletServers_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.LIST, 0)
-      oprot.writeListBegin(TType.STRING, len(self.success))
-      for iter359 in self.success:
-        oprot.writeString(iter359)
-      oprot.writeListEnd()
-      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 removeProperty_args:
-  """
-  Attributes:
-   - login
-   - property
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'property', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, property=None,):
-    self.login = login
-    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.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('removeProperty_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.property is not None:
-      oprot.writeFieldBegin('property', TType.STRING, 2)
-      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.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 removeProperty_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('removeProperty_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 setProperty_args:
-  """
-  Attributes:
-   - login
-   - property
-   - value
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'property', None, None, ), # 2
-    (3, TType.STRING, 'value', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, property=None, value=None,):
-    self.login = login
-    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.property = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        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('setProperty_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.property is not None:
-      oprot.writeFieldBegin('property', TType.STRING, 2)
-      oprot.writeString(self.property)
-      oprot.writeFieldEnd()
-    if self.value is not None:
-      oprot.writeFieldBegin('value', TType.STRING, 3)
-      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.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 setProperty_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('setProperty_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 testClassLoad_args:
-  """
-  Attributes:
-   - login
-   - className
-   - asTypeName
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'className', None, None, ), # 2
-    (3, TType.STRING, 'asTypeName', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, className=None, asTypeName=None,):
-    self.login = login
-    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.className = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        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('testClassLoad_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.className is not None:
-      oprot.writeFieldBegin('className', TType.STRING, 2)
-      oprot.writeString(self.className)
-      oprot.writeFieldEnd()
-    if self.asTypeName is not None:
-      oprot.writeFieldBegin('asTypeName', TType.STRING, 3)
-      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.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 testClassLoad_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('testClassLoad_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 authenticateUser_args:
-  """
-  Attributes:
-   - login
-   - user
-   - properties
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.MAP, 'properties', (TType.STRING,None,TType.STRING,None), None, ), # 3
-  )
-
-  def __init__(self, login=None, user=None, properties=None,):
-    self.login = login
-    self.user = user
-    self.properties = properties
-
-  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.MAP:
-          self.properties = {}
-          (_ktype361, _vtype362, _size360 ) = iprot.readMapBegin()
-          for _i364 in xrange(_size360):
-            _key365 = iprot.readString()
-            _val366 = iprot.readString()
-            self.properties[_key365] = _val366
-          iprot.readMapEnd()
-        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('authenticateUser_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.properties is not None:
-      oprot.writeFieldBegin('properties', TType.MAP, 3)
-      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.properties))
-      for kiter367,viter368 in self.properties.items():
-        oprot.writeString(kiter367)
-        oprot.writeString(viter368)
-      oprot.writeMapEnd()
-      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.properties)
-    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 authenticateUser_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('authenticateUser_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 changeUserAuthorizations_args:
-  """
-  Attributes:
-   - login
-   - user
-   - authorizations
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.SET, 'authorizations', (TType.STRING,None), None, ), # 3
-  )
-
-  def __init__(self, login=None, user=None, authorizations=None,):
-    self.login = login
-    self.user = user
-    self.authorizations = authorizations
-
-  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.SET:
-          self.authorizations = set()
-          (_etype372, _size369) = iprot.readSetBegin()
-          for _i373 in xrange(_size369):
-            _elem374 = iprot.readString()
-            self.authorizations.add(_elem374)
-          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('changeUserAuthorizations_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.authorizations is not None:
-      oprot.writeFieldBegin('authorizations', TType.SET, 3)
-      oprot.writeSetBegin(TType.STRING, len(self.authorizations))
-      for iter375 in self.authorizations:
-        oprot.writeString(iter375)
-      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.user)
-    value = (value * 31) ^ hash(self.authorizations)
-    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 changeUserAuthorizations_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('changeUserAuthorizations_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 changeLocalUserPassword_args:
-  """
-  Attributes:
-   - login
-   - user
-   - password
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.STRING, 'password', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, user=None, password=None,):
-    self.login = login
-    self.user = user
-    self.password = password
-
-  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.password = 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('changeLocalUserPassword_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.password is not None:
-      oprot.writeFieldBegin('password', TType.STRING, 3)
-      oprot.writeString(self.password)
-      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.password)
-    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 changeLocalUserPassword_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('changeLocalUserPassword_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 createLocalUser_args:
-  """
-  Attributes:
-   - login
-   - user
-   - password
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.STRING, 'password', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, user=None, password=None,):
-    self.login = login
-    self.user = user
-    self.password = password
-
-  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.password = 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('createLocalUser_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.password is not None:
-      oprot.writeFieldBegin('password', TType.STRING, 3)
-      oprot.writeString(self.password)
-      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.password)
-    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 createLocalUser_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('createLocalUser_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 dropLocalUser_args:
-  """
-  Attributes:
-   - login
-   - user
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, user=None,):
-    self.login = login
-    self.user = user
-
-  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)
-      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('dropLocalUser_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()
-    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)
-    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 dropLocalUser_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('dropLocalUser_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 getUserAuthorizations_args:
-  """
-  Attributes:
-   - login
-   - user
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-  )
-
-  def __init__(self, login=None, user=None,):
-    self.login = login
-    self.user = user
-
-  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)
-      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('getUserAuthorizations_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()
-    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)
-    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 getUserAuthorizations_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 = []
-          (_etype379, _size376) = iprot.readListBegin()
-          for _i380 in xrange(_size376):
-            _elem381 = iprot.readString()
-            self.success.append(_elem381)
-          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('getUserAuthorizations_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.LIST, 0)
-      oprot.writeListBegin(TType.STRING, len(self.success))
-      for iter382 in self.success:
-        oprot.writeString(iter382)
-      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 grantSystemPermission_args:
-  """
-  Attributes:
-   - login
-   - user
-   - perm
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.I32, 'perm', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, user=None, perm=None,):
-    self.login = login
-    self.user = user
-    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.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('grantSystemPermission_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.perm is not None:
-      oprot.writeFieldBegin('perm', TType.I32, 3)
-      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.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 grantSystemPermission_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('grantSystemPermission_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 grantTablePermission_args:
-  """
-  Attributes:
-   - login
-   - user
-   - table
-   - perm
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.STRING, 'table', None, None, ), # 3
-    (4, TType.I32, 'perm', None, None, ), # 4
-  )
-
-  def __init__(self, login=None, user=None, table=None, perm=None,):
-    self.login = login
-    self.user = user
-    self.table = table
-    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.table = 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('grantTablePermission_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.table is not None:
-      oprot.writeFieldBegin('table', TType.STRING, 3)
-      oprot.writeString(self.table)
-      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.table)
-    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 grantTablePermission_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('grantTablePermission_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 hasSystemPermission_args:
-  """
-  Attributes:
-   - login
-   - user
-   - perm
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.I32, 'perm', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, user=None, perm=None,):
-    self.login = login
-    self.user = user
-    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.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('hasSystemPermission_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.perm is not None:
-      oprot.writeFieldBegin('perm', TType.I32, 3)
-      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.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 hasSystemPermission_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('hasSystemPermission_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 hasTablePermission_args:
-  """
-  Attributes:
-   - login
-   - user
-   - table
-   - perm
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.STRING, 'table', None, None, ), # 3
-    (4, TType.I32, 'perm', None, None, ), # 4
-  )
-
-  def __init__(self, login=None, user=None, table=None, perm=None,):
-    self.login = login
-    self.user = user
-    self.table = table
-    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.table = 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('hasTablePermission_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.table is not None:
-      oprot.writeFieldBegin('table', TType.STRING, 3)
-      oprot.writeString(self.table)
-      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.table)
-    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 hasTablePermission_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('hasTablePermission_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()]
-    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 listLocalUsers_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('listLocalUsers_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 listLocalUsers_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.SET, '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
-    (3, TType.STRUCT, 'ouch3', (TableNotFoundException, TableNotFoundException.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.SET:
-          self.success = set()
-          (_etype386, _size383) = iprot.readSetBegin()
-          for _i387 in xrange(_size383):
-            _elem388 = iprot.readString()
-            self.success.add(_elem388)
-          iprot.readSetEnd()
-        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 = TableNotFoundException()
-          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('listLocalUsers_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.SET, 0)
-      oprot.writeSetBegin(TType.STRING, len(self.success))
-      for iter389 in self.success:
-        oprot.writeString(iter389)
-      oprot.writeSetEnd()
-      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 revokeSystemPermission_args:
-  """
-  Attributes:
-   - login
-   - user
-   - perm
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.I32, 'perm', None, None, ), # 3
-  )
-
-  def __init__(self, login=None, user=None, perm=None,):
-    self.login = login
-    self.user = user
-    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.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('revokeSystemPermission_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.perm is not None:
-      oprot.writeFieldBegin('perm', TType.I32, 3)
-      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.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 revokeSystemPermission_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('revokeSystemPermission_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 revokeTablePermission_args:
-  """
-  Attributes:
-   - login
-   - user
-   - table
-   - perm
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.STRING, 'table', None, None, ), # 3
-    (4, TType.I32, 'perm', None, None, ), # 4
-  )
-
-  def __init__(self, login=None, user=None, table=None, perm=None,):
-    self.login = login
-    self.user = user
-    self.table = table
-    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.table = 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('revokeTablePermission_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.table is not None:
-      oprot.writeFieldBegin('table', TType.STRING, 3)
-      oprot.writeString(self.table)
-      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.table)
-    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 revokeTablePermission_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('revokeTablePermission_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 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()]
-    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 createBatchScanner_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - options
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRUCT, 'options', (BatchScanOptions, BatchScanOptions.thrift_spec), None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, options=None,):
-    self.login = login
-    self.tableName = tableName
-    self.options = options
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.options = BatchScanOptions()
-          self.options.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('createBatchScanner_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.options is not None:
-      oprot.writeFieldBegin('options', TType.STRUCT, 3)
-      self.options.write(oprot)
-      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.tableName)
-    value = (value * 31) ^ hash(self.options)
-    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 createBatchScanner_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.STRING, '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', (TableNotFoundException, TableNotFoundException.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.STRING:
-          self.success = iprot.readString()
-        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 = TableNotFoundException()
-          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('createBatchScanner_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.STRING, 0)
-      oprot.writeString(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 createScanner_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - options
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRUCT, 'options', (ScanOptions, ScanOptions.thrift_spec), None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, options=None,):
-    self.login = login
-    self.tableName = tableName
-    self.options = options
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.options = ScanOptions()
-          self.options.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('createScanner_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.options is not None:
-      oprot.writeFieldBegin('options', TType.STRUCT, 3)
-      self.options.write(oprot)
-      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.tableName)
-    value = (value * 31) ^ hash(self.options)
-    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 createScanner_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.STRING, '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', (TableNotFoundException, TableNotFoundException.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.STRING:
-          self.success = iprot.readString()
-        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 = TableNotFoundException()
-          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('createScanner_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.STRING, 0)
-      oprot.writeString(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 hasNext_args:
-  """
-  Attributes:
-   - scanner
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'scanner', None, None, ), # 1
-  )
-
-  def __init__(self, scanner=None,):
-    self.scanner = scanner
-
-  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.scanner = 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('hasNext_args')
-    if self.scanner is not None:
-      oprot.writeFieldBegin('scanner', TType.STRING, 1)
-      oprot.writeString(self.scanner)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 hasNext_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-  """
-
-  thrift_spec = (
-    (0, TType.BOOL, 'success', None, None, ), # 0
-    (1, TType.STRUCT, 'ouch1', (UnknownScanner, UnknownScanner.thrift_spec), None, ), # 1
-  )
-
-  def __init__(self, success=None, ouch1=None,):
-    self.success = success
-    self.ouch1 = ouch1
-
-  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 = UnknownScanner()
-          self.ouch1.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('hasNext_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()
-    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)
-    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 nextEntry_args:
-  """
-  Attributes:
-   - scanner
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'scanner', None, None, ), # 1
-  )
-
-  def __init__(self, scanner=None,):
-    self.scanner = scanner
-
-  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.scanner = 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('nextEntry_args')
-    if self.scanner is not None:
-      oprot.writeFieldBegin('scanner', TType.STRING, 1)
-      oprot.writeString(self.scanner)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 nextEntry_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.STRUCT, 'success', (KeyValueAndPeek, KeyValueAndPeek.thrift_spec), None, ), # 0
-    (1, TType.STRUCT, 'ouch1', (NoMoreEntriesException, NoMoreEntriesException.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (UnknownScanner, UnknownScanner.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch3', (AccumuloSecurityException, AccumuloSecurityException.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 = KeyValueAndPeek()
-          self.success.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 1:
-        if ftype == TType.STRUCT:
-          self.ouch1 = NoMoreEntriesException()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch2 = UnknownScanner()
-          self.ouch2.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch3 = AccumuloSecurityException()
-          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('nextEntry_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 nextK_args:
-  """
-  Attributes:
-   - scanner
-   - k
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'scanner', None, None, ), # 1
-    (2, TType.I32, 'k', None, None, ), # 2
-  )
-
-  def __init__(self, scanner=None, k=None,):
-    self.scanner = scanner
-    self.k = k
-
-  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.scanner = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.I32:
-          self.k = 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('nextK_args')
-    if self.scanner is not None:
-      oprot.writeFieldBegin('scanner', TType.STRING, 1)
-      oprot.writeString(self.scanner)
-      oprot.writeFieldEnd()
-    if self.k is not None:
-      oprot.writeFieldBegin('k', TType.I32, 2)
-      oprot.writeI32(self.k)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 nextK_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.STRUCT, 'success', (ScanResult, ScanResult.thrift_spec), None, ), # 0
-    (1, TType.STRUCT, 'ouch1', (NoMoreEntriesException, NoMoreEntriesException.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (UnknownScanner, UnknownScanner.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch3', (AccumuloSecurityException, AccumuloSecurityException.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 = ScanResult()
-          self.success.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 1:
-        if ftype == TType.STRUCT:
-          self.ouch1 = NoMoreEntriesException()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch2 = UnknownScanner()
-          self.ouch2.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch3 = AccumuloSecurityException()
-          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('nextK_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 closeScanner_args:
-  """
-  Attributes:
-   - scanner
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'scanner', None, None, ), # 1
-  )
-
-  def __init__(self, scanner=None,):
-    self.scanner = scanner
-
-  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.scanner = 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('closeScanner_args')
-    if self.scanner is not None:
-      oprot.writeFieldBegin('scanner', TType.STRING, 1)
-      oprot.writeString(self.scanner)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 closeScanner_result:
-  """
-  Attributes:
-   - ouch1
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'ouch1', (UnknownScanner, UnknownScanner.thrift_spec), None, ), # 1
-  )
-
-  def __init__(self, ouch1=None,):
-    self.ouch1 = ouch1
-
-  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 = UnknownScanner()
-          self.ouch1.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('closeScanner_result')
-    if self.ouch1 is not None:
-      oprot.writeFieldBegin('ouch1', TType.STRUCT, 1)
-      self.ouch1.write(oprot)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 updateAndFlush_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - cells
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.MAP, 'cells', (TType.STRING,None,TType.LIST,(TType.STRUCT,(ColumnUpdate, ColumnUpdate.thrift_spec))), None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, cells=None,):
-    self.login = login
-    self.tableName = tableName
-    self.cells = cells
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.MAP:
-          self.cells = {}
-          (_ktype391, _vtype392, _size390 ) = iprot.readMapBegin()
-          for _i394 in xrange(_size390):
-            _key395 = iprot.readString()
-            _val396 = []
-            (_etype400, _size397) = iprot.readListBegin()
-            for _i401 in xrange(_size397):
-              _elem402 = ColumnUpdate()
-              _elem402.read(iprot)
-              _val396.append(_elem402)
-            iprot.readListEnd()
-            self.cells[_key395] = _val396
-          iprot.readMapEnd()
-        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('updateAndFlush_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.cells is not None:
-      oprot.writeFieldBegin('cells', TType.MAP, 3)
-      oprot.writeMapBegin(TType.STRING, TType.LIST, len(self.cells))
-      for kiter403,viter404 in self.cells.items():
-        oprot.writeString(kiter403)
-        oprot.writeListBegin(TType.STRUCT, len(viter404))
-        for iter405 in viter404:
-          iter405.write(oprot)
-        oprot.writeListEnd()
-      oprot.writeMapEnd()
-      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.tableName)
-    value = (value * 31) ^ hash(self.cells)
-    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 updateAndFlush_result:
-  """
-  Attributes:
-   - outch1
-   - ouch2
-   - ouch3
-   - ouch4
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'outch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch3', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ), # 3
-    (4, TType.STRUCT, 'ouch4', (MutationsRejectedException, MutationsRejectedException.thrift_spec), None, ), # 4
-  )
-
-  def __init__(self, outch1=None, ouch2=None, ouch3=None, ouch4=None,):
-    self.outch1 = outch1
-    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.outch1 = AccumuloException()
-          self.outch1.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 = TableNotFoundException()
-          self.ouch3.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRUCT:
-          self.ouch4 = MutationsRejectedException()
-          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('updateAndFlush_result')
-    if self.outch1 is not None:
-      oprot.writeFieldBegin('outch1', TType.STRUCT, 1)
-      self.outch1.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.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()]
-    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 createWriter_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - opts
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRUCT, 'opts', (WriterOptions, WriterOptions.thrift_spec), None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, opts=None,):
-    self.login = login
-    self.tableName = tableName
-    self.opts = opts
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.opts = WriterOptions()
-          self.opts.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('createWriter_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.opts is not None:
-      oprot.writeFieldBegin('opts', TType.STRUCT, 3)
-      self.opts.write(oprot)
-      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.tableName)
-    value = (value * 31) ^ hash(self.opts)
-    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 createWriter_result:
-  """
-  Attributes:
-   - success
-   - outch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.STRING, 'success', None, None, ), # 0
-    (1, TType.STRUCT, 'outch1', (AccumuloException, AccumuloException.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (AccumuloSecurityException, AccumuloSecurityException.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch3', (TableNotFoundException, TableNotFoundException.thrift_spec), None, ), # 3
-  )
-
-  def __init__(self, success=None, outch1=None, ouch2=None, ouch3=None,):
-    self.success = success
-    self.outch1 = outch1
-    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.STRING:
-          self.success = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 1:
-        if ftype == TType.STRUCT:
-          self.outch1 = AccumuloException()
-          self.outch1.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 = TableNotFoundException()
-          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('createWriter_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.STRING, 0)
-      oprot.writeString(self.success)
-      oprot.writeFieldEnd()
-    if self.outch1 is not None:
-      oprot.writeFieldBegin('outch1', TType.STRUCT, 1)
-      self.outch1.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.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()]
-    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 update_args:
-  """
-  Attributes:
-   - writer
-   - cells
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'writer', None, None, ), # 1
-    (2, TType.MAP, 'cells', (TType.STRING,None,TType.LIST,(TType.STRUCT,(ColumnUpdate, ColumnUpdate.thrift_spec))), None, ), # 2
-  )
-
-  def __init__(self, writer=None, cells=None,):
-    self.writer = writer
-    self.cells = cells
-
-  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.writer = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.MAP:
-          self.cells = {}
-          (_ktype407, _vtype408, _size406 ) = iprot.readMapBegin()
-          for _i410 in xrange(_size406):
-            _key411 = iprot.readString()
-            _val412 = []
-            (_etype416, _size413) = iprot.readListBegin()
-            for _i417 in xrange(_size413):
-              _elem418 = ColumnUpdate()
-              _elem418.read(iprot)
-              _val412.append(_elem418)
-            iprot.readListEnd()
-            self.cells[_key411] = _val412
-          iprot.readMapEnd()
-        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('update_args')
-    if self.writer is not None:
-      oprot.writeFieldBegin('writer', TType.STRING, 1)
-      oprot.writeString(self.writer)
-      oprot.writeFieldEnd()
-    if self.cells is not None:
-      oprot.writeFieldBegin('cells', TType.MAP, 2)
-      oprot.writeMapBegin(TType.STRING, TType.LIST, len(self.cells))
-      for kiter419,viter420 in self.cells.items():
-        oprot.writeString(kiter419)
-        oprot.writeListBegin(TType.STRUCT, len(viter420))
-        for iter421 in viter420:
-          iter421.write(oprot)
-        oprot.writeListEnd()
-      oprot.writeMapEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 flush_args:
-  """
-  Attributes:
-   - writer
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'writer', None, None, ), # 1
-  )
-
-  def __init__(self, writer=None,):
-    self.writer = writer
-
-  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.writer = 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('flush_args')
-    if self.writer is not None:
-      oprot.writeFieldBegin('writer', TType.STRING, 1)
-      oprot.writeString(self.writer)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 flush_result:
-  """
-  Attributes:
-   - ouch1
-   - ouch2
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'ouch1', (UnknownWriter, UnknownWriter.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (MutationsRejectedException, MutationsRejectedException.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 = UnknownWriter()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch2 = MutationsRejectedException()
-          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('flush_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 closeWriter_args:
-  """
-  Attributes:
-   - writer
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'writer', None, None, ), # 1
-  )
-
-  def __init__(self, writer=None,):
-    self.writer = writer
-
-  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.writer = 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('closeWriter_args')
-    if self.writer is not None:
-      oprot.writeFieldBegin('writer', TType.STRING, 1)
-      oprot.writeString(self.writer)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 closeWriter_result:
-  """
-  Attributes:
-   - ouch1
-   - ouch2
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'ouch1', (UnknownWriter, UnknownWriter.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (MutationsRejectedException, MutationsRejectedException.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 = UnknownWriter()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch2 = MutationsRejectedException()
-          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('closeWriter_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 updateRowConditionally_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - row
-   - updates
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRING, 'row', None, None, ), # 3
-    (4, TType.STRUCT, 'updates', (ConditionalUpdates, ConditionalUpdates.thrift_spec), None, ), # 4
-  )
-
-  def __init__(self, login=None, tableName=None, row=None, updates=None,):
-    self.login = login
-    self.tableName = tableName
-    self.row = row
-    self.updates = updates
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.row = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRUCT:
-          self.updates = ConditionalUpdates()
-          self.updates.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('updateRowConditionally_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.row is not None:
-      oprot.writeFieldBegin('row', TType.STRING, 3)
-      oprot.writeString(self.row)
-      oprot.writeFieldEnd()
-    if self.updates is not None:
-      oprot.writeFieldBegin('updates', TType.STRUCT, 4)
-      self.updates.write(oprot)
-      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.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()]
-    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 updateRowConditionally_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', (TableNotFoundException, TableNotFoundException.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 = TableNotFoundException()
-          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('updateRowConditionally_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 createConditionalWriter_args:
-  """
-  Attributes:
-   - login
-   - tableName
-   - options
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'login', None, None, ), # 1
-    (2, TType.STRING, 'tableName', None, None, ), # 2
-    (3, TType.STRUCT, 'options', (ConditionalWriterOptions, ConditionalWriterOptions.thrift_spec), None, ), # 3
-  )
-
-  def __init__(self, login=None, tableName=None, options=None,):
-    self.login = login
-    self.tableName = tableName
-    self.options = options
-
-  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.tableName = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.options = ConditionalWriterOptions()
-          self.options.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('createConditionalWriter_args')
-    if self.login is not None:
-      oprot.writeFieldBegin('login', TType.STRING, 1)
-      oprot.writeString(self.login)
-      oprot.writeFieldEnd()
-    if self.tableName is not None:
-      oprot.writeFieldBegin('tableName', TType.STRING, 2)
-      oprot.writeString(self.tableName)
-      oprot.writeFieldEnd()
-    if self.options is not None:
-      oprot.writeFieldBegin('options', TType.STRUCT, 3)
-      self.options.write(oprot)
-      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.tableName)
-    value = (value * 31) ^ hash(self.options)
-    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 createConditionalWriter_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.STRING, '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', (TableNotFoundException, TableNotFoundException.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.STRING:
-          self.success = iprot.readString()
-        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 = TableNotFoundException()
-          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('createConditionalWriter_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.STRING, 0)
-      oprot.writeString(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 updateRowsConditionally_args:
-  """
-  Attributes:
-   - conditionalWriter
-   - updates
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'conditionalWriter', None, None, ), # 1
-    (2, TType.MAP, 'updates', (TType.STRING,None,TType.STRUCT,(ConditionalUpdates, ConditionalUpdates.thrift_spec)), None, ), # 2
-  )
-
-  def __init__(self, conditionalWriter=None, updates=None,):
-    self.conditionalWriter = conditionalWriter
-    self.updates = updates
-
-  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.conditionalWriter = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.MAP:
-          self.updates = {}
-          (_ktype423, _vtype424, _size422 ) = iprot.readMapBegin()
-          for _i426 in xrange(_size422):
-            _key427 = iprot.readString()
-            _val428 = ConditionalUpdates()
-            _val428.read(iprot)
-            self.updates[_key427] = _val428
-          iprot.readMapEnd()
-        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('updateRowsConditionally_args')
-    if self.conditionalWriter is not None:
-      oprot.writeFieldBegin('conditionalWriter', TType.STRING, 1)
-      oprot.writeString(self.conditionalWriter)
-      oprot.writeFieldEnd()
-    if self.updates is not None:
-      oprot.writeFieldBegin('updates', TType.MAP, 2)
-      oprot.writeMapBegin(TType.STRING, TType.STRUCT, len(self.updates))
-      for kiter429,viter430 in self.updates.items():
-        oprot.writeString(kiter429)
-        viter430.write(oprot)
-      oprot.writeMapEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 updateRowsConditionally_result:
-  """
-  Attributes:
-   - success
-   - ouch1
-   - ouch2
-   - ouch3
-  """
-
-  thrift_spec = (
-    (0, TType.MAP, 'success', (TType.STRING,None,TType.I32,None), None, ), # 0
-    (1, TType.STRUCT, 'ouch1', (UnknownWriter, UnknownWriter.thrift_spec), None, ), # 1
-    (2, TType.STRUCT, 'ouch2', (AccumuloException, AccumuloException.thrift_spec), None, ), # 2
-    (3, TType.STRUCT, 'ouch3', (AccumuloSecurityException, AccumuloSecurityException.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 = {}
-          (_ktype432, _vtype433, _size431 ) = iprot.readMapBegin()
-          for _i435 in xrange(_size431):
-            _key436 = iprot.readString()
-            _val437 = iprot.readI32()
-            self.success[_key436] = _val437
-          iprot.readMapEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 1:
-        if ftype == TType.STRUCT:
-          self.ouch1 = UnknownWriter()
-          self.ouch1.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.ouch2 = AccumuloException()
-          self.ouch2.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.ouch3 = AccumuloSecurityException()
-          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('updateRowsConditionally_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.MAP, 0)
-      oprot.writeMapBegin(TType.STRING, TType.I32, len(self.success))
-      for kiter438,viter439 in self.success.items():
-        oprot.writeString(kiter438)
-        oprot.writeI32(viter439)
-      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 closeConditionalWriter_args:
-  """
-  Attributes:
-   - conditionalWriter
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'conditionalWriter', None, None, ), # 1
-  )
-
-  def __init__(self, conditionalWriter=None,):
-    self.conditionalWriter = conditionalWriter
-
-  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.conditionalWriter = 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('closeConditionalWriter_args')
-    if self.conditionalWriter is not None:
-      oprot.writeFieldBegin('conditionalWriter', TType.STRING, 1)
-      oprot.writeString(self.conditionalWriter)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 closeConditionalWriter_result:
-
-  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('closeConditionalWriter_result')
-    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 getRowRange_args:
-  """
-  Attributes:
-   - row
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'row', None, None, ), # 1
-  )
-
-  def __init__(self, row=None,):
-    self.row = row
-
-  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.row = 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('getRowRange_args')
-    if self.row is not None:
-      oprot.writeFieldBegin('row', TType.STRING, 1)
-      oprot.writeString(self.row)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 getRowRange_result:
-  """
-  Attributes:
-   - success
-  """
-
-  thrift_spec = (
-    (0, TType.STRUCT, 'success', (Range, Range.thrift_spec), 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.STRUCT:
-          self.success = Range()
-          self.success.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('getRowRange_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.STRUCT, 0)
-      self.success.write(oprot)
-      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 getFollowing_args:
-  """
-  Attributes:
-   - key
-   - part
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'key', (Key, Key.thrift_spec), None, ), # 1
-    (2, TType.I32, 'part', None, None, ), # 2
-  )
-
-  def __init__(self, key=None, part=None,):
-    self.key = key
-    self.part = part
-
-  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.key = Key()
-          self.key.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.I32:
-          self.part = 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('getFollowing_args')
-    if self.key is not None:
-      oprot.writeFieldBegin('key', TType.STRUCT, 1)
-      self.key.write(oprot)
-      oprot.writeFieldEnd()
-    if self.part is not None:
-      oprot.writeFieldBegin('part', TType.I32, 2)
-      oprot.writeI32(self.part)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
-
-  def validate(self):
-    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()]
-    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 getFollowing_result:
-  """
-  Attributes:
-   - success
-  """
-
-  thrift_spec = (
-    (0, TType.STRUCT, 'success', (Key, Key.thrift_spec), 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.STRUCT:
-          self.success = Key()
-          self.success.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('getFollowing_result')
-    if self.success is not None:
-      oprot.writeFieldBegin('success', TType.STRUCT, 0)
-      self.success.write(oprot)
-      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 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()]
-    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)
+    def __ne__(self, other):
+        return not (self == other)
diff --git a/src/main/python/constants.py b/src/main/python/constants.py
index 8139236..3b2f97a 100644
--- a/src/main/python/constants.py
+++ b/src/main/python/constants.py
@@ -13,13 +13,14 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Autogenerated by Thrift Compiler (0.9.3)
+# Autogenerated by Thrift Compiler (0.10.0)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
 #  options string: py
 #
 
-from thrift.Thrift import TType, TMessageType, TException, TApplicationException
-from ttypes import *
-
+from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException
+from thrift.protocol.TProtocol import TProtocolException
+import sys
+from .ttypes import *
diff --git a/src/main/python/ttypes.py b/src/main/python/ttypes.py
index 3f9ec9c..ca90543 100644
--- a/src/main/python/ttypes.py
+++ b/src/main/python/ttypes.py
@@ -13,3367 +13,3155 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Autogenerated by Thrift Compiler (0.9.3)
+# Autogenerated by Thrift Compiler (0.10.0)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
 #  options string: py
 #
 
-from thrift.Thrift import TType, TMessageType, TException, TApplicationException
+from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException
+from thrift.protocol.TProtocol import TProtocolException
+import sys
 
 from thrift.transport import TTransport
-from thrift.protocol import TBinaryProtocol, TProtocol
-try:
-  from thrift.protocol import fastbinary
-except:
-  fastbinary = None
 
 
-class PartialKey:
-  ROW = 0
-  ROW_COLFAM = 1
-  ROW_COLFAM_COLQUAL = 2
-  ROW_COLFAM_COLQUAL_COLVIS = 3
-  ROW_COLFAM_COLQUAL_COLVIS_TIME = 4
-  ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL = 5
+class PartialKey(object):
+    ROW = 0
+    ROW_COLFAM = 1
+    ROW_COLFAM_COLQUAL = 2
+    ROW_COLFAM_COLQUAL_COLVIS = 3
+    ROW_COLFAM_COLQUAL_COLVIS_TIME = 4
+    ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL = 5
 
-  _VALUES_TO_NAMES = {
-    0: "ROW",
-    1: "ROW_COLFAM",
-    2: "ROW_COLFAM_COLQUAL",
-    3: "ROW_COLFAM_COLQUAL_COLVIS",
-    4: "ROW_COLFAM_COLQUAL_COLVIS_TIME",
-    5: "ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL",
-  }
+    _VALUES_TO_NAMES = {
+        0: "ROW",
+        1: "ROW_COLFAM",
+        2: "ROW_COLFAM_COLQUAL",
+        3: "ROW_COLFAM_COLQUAL_COLVIS",
+        4: "ROW_COLFAM_COLQUAL_COLVIS_TIME",
+        5: "ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL",
+    }
 
-  _NAMES_TO_VALUES = {
-    "ROW": 0,
-    "ROW_COLFAM": 1,
-    "ROW_COLFAM_COLQUAL": 2,
-    "ROW_COLFAM_COLQUAL_COLVIS": 3,
-    "ROW_COLFAM_COLQUAL_COLVIS_TIME": 4,
-    "ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL": 5,
-  }
+    _NAMES_TO_VALUES = {
+        "ROW": 0,
+        "ROW_COLFAM": 1,
+        "ROW_COLFAM_COLQUAL": 2,
+        "ROW_COLFAM_COLQUAL_COLVIS": 3,
+        "ROW_COLFAM_COLQUAL_COLVIS_TIME": 4,
+        "ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL": 5,
+    }
 
-class TablePermission:
-  READ = 2
-  WRITE = 3
-  BULK_IMPORT = 4
-  ALTER_TABLE = 5
-  GRANT = 6
-  DROP_TABLE = 7
 
-  _VALUES_TO_NAMES = {
-    2: "READ",
-    3: "WRITE",
-    4: "BULK_IMPORT",
-    5: "ALTER_TABLE",
-    6: "GRANT",
-    7: "DROP_TABLE",
-  }
+class TablePermission(object):
+    READ = 2
+    WRITE = 3
+    BULK_IMPORT = 4
+    ALTER_TABLE = 5
+    GRANT = 6
+    DROP_TABLE = 7
 
-  _NAMES_TO_VALUES = {
-    "READ": 2,
-    "WRITE": 3,
-    "BULK_IMPORT": 4,
-    "ALTER_TABLE": 5,
-    "GRANT": 6,
-    "DROP_TABLE": 7,
-  }
+    _VALUES_TO_NAMES = {
+        2: "READ",
+        3: "WRITE",
+        4: "BULK_IMPORT",
+        5: "ALTER_TABLE",
+        6: "GRANT",
+        7: "DROP_TABLE",
+    }
 
-class SystemPermission:
-  GRANT = 0
-  CREATE_TABLE = 1
-  DROP_TABLE = 2
-  ALTER_TABLE = 3
-  CREATE_USER = 4
-  DROP_USER = 5
-  ALTER_USER = 6
-  SYSTEM = 7
-  CREATE_NAMESPACE = 8
-  DROP_NAMESPACE = 9
-  ALTER_NAMESPACE = 10
-  OBTAIN_DELEGATION_TOKEN = 11
+    _NAMES_TO_VALUES = {
+        "READ": 2,
+        "WRITE": 3,
+        "BULK_IMPORT": 4,
+        "ALTER_TABLE": 5,
+        "GRANT": 6,
+        "DROP_TABLE": 7,
+    }
 
-  _VALUES_TO_NAMES = {
-    0: "GRANT",
-    1: "CREATE_TABLE",
-    2: "DROP_TABLE",
-    3: "ALTER_TABLE",
-    4: "CREATE_USER",
-    5: "DROP_USER",
-    6: "ALTER_USER",
-    7: "SYSTEM",
-    8: "CREATE_NAMESPACE",
-    9: "DROP_NAMESPACE",
-    10: "ALTER_NAMESPACE",
-    11: "OBTAIN_DELEGATION_TOKEN",
-  }
 
-  _NAMES_TO_VALUES = {
-    "GRANT": 0,
-    "CREATE_TABLE": 1,
-    "DROP_TABLE": 2,
-    "ALTER_TABLE": 3,
-    "CREATE_USER": 4,
-    "DROP_USER": 5,
-    "ALTER_USER": 6,
-    "SYSTEM": 7,
-    "CREATE_NAMESPACE": 8,
-    "DROP_NAMESPACE": 9,
-    "ALTER_NAMESPACE": 10,
-    "OBTAIN_DELEGATION_TOKEN": 11,
-  }
+class SystemPermission(object):
+    GRANT = 0
+    CREATE_TABLE = 1
+    DROP_TABLE = 2
+    ALTER_TABLE = 3
+    CREATE_USER = 4
+    DROP_USER = 5
+    ALTER_USER = 6
+    SYSTEM = 7
+    CREATE_NAMESPACE = 8
+    DROP_NAMESPACE = 9
+    ALTER_NAMESPACE = 10
+    OBTAIN_DELEGATION_TOKEN = 11
 
-class NamespacePermission:
-  READ = 0
-  WRITE = 1
-  ALTER_NAMESPACE = 2
-  GRANT = 3
-  ALTER_TABLE = 4
-  CREATE_TABLE = 5
-  DROP_TABLE = 6
-  BULK_IMPORT = 7
-  DROP_NAMESPACE = 8
+    _VALUES_TO_NAMES = {
+        0: "GRANT",
+        1: "CREATE_TABLE",
+        2: "DROP_TABLE",
+        3: "ALTER_TABLE",
+        4: "CREATE_USER",
+        5: "DROP_USER",
+        6: "ALTER_USER",
+        7: "SYSTEM",
+        8: "CREATE_NAMESPACE",
+        9: "DROP_NAMESPACE",
+        10: "ALTER_NAMESPACE",
+        11: "OBTAIN_DELEGATION_TOKEN",
+    }
 
-  _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 = {
+        "GRANT": 0,
+        "CREATE_TABLE": 1,
+        "DROP_TABLE": 2,
+        "ALTER_TABLE": 3,
+        "CREATE_USER": 4,
+        "DROP_USER": 5,
+        "ALTER_USER": 6,
+        "SYSTEM": 7,
+        "CREATE_NAMESPACE": 8,
+        "DROP_NAMESPACE": 9,
+        "ALTER_NAMESPACE": 10,
+        "OBTAIN_DELEGATION_TOKEN": 11,
+    }
 
-  _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
+class NamespacePermission(object):
+    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: "SINGLE",
-    1: "BATCH",
-  }
+    _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 = {
-    "SINGLE": 0,
-    "BATCH": 1,
-  }
+    _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 ScanState:
-  IDLE = 0
-  RUNNING = 1
-  QUEUED = 2
 
-  _VALUES_TO_NAMES = {
-    0: "IDLE",
-    1: "RUNNING",
-    2: "QUEUED",
-  }
+class ScanType(object):
+    SINGLE = 0
+    BATCH = 1
 
-  _NAMES_TO_VALUES = {
-    "IDLE": 0,
-    "RUNNING": 1,
-    "QUEUED": 2,
-  }
+    _VALUES_TO_NAMES = {
+        0: "SINGLE",
+        1: "BATCH",
+    }
 
-class ConditionalStatus:
-  ACCEPTED = 0
-  REJECTED = 1
-  VIOLATED = 2
-  UNKNOWN = 3
-  INVISIBLE_VISIBILITY = 4
+    _NAMES_TO_VALUES = {
+        "SINGLE": 0,
+        "BATCH": 1,
+    }
 
-  _VALUES_TO_NAMES = {
-    0: "ACCEPTED",
-    1: "REJECTED",
-    2: "VIOLATED",
-    3: "UNKNOWN",
-    4: "INVISIBLE_VISIBILITY",
-  }
 
-  _NAMES_TO_VALUES = {
-    "ACCEPTED": 0,
-    "REJECTED": 1,
-    "VIOLATED": 2,
-    "UNKNOWN": 3,
-    "INVISIBLE_VISIBILITY": 4,
-  }
+class ScanState(object):
+    IDLE = 0
+    RUNNING = 1
+    QUEUED = 2
 
-class Durability:
-  DEFAULT = 0
-  NONE = 1
-  LOG = 2
-  FLUSH = 3
-  SYNC = 4
+    _VALUES_TO_NAMES = {
+        0: "IDLE",
+        1: "RUNNING",
+        2: "QUEUED",
+    }
 
-  _VALUES_TO_NAMES = {
-    0: "DEFAULT",
-    1: "NONE",
-    2: "LOG",
-    3: "FLUSH",
-    4: "SYNC",
-  }
+    _NAMES_TO_VALUES = {
+        "IDLE": 0,
+        "RUNNING": 1,
+        "QUEUED": 2,
+    }
 
-  _NAMES_TO_VALUES = {
-    "DEFAULT": 0,
-    "NONE": 1,
-    "LOG": 2,
-    "FLUSH": 3,
-    "SYNC": 4,
-  }
 
-class CompactionType:
-  MINOR = 0
-  MERGE = 1
-  MAJOR = 2
-  FULL = 3
+class ConditionalStatus(object):
+    ACCEPTED = 0
+    REJECTED = 1
+    VIOLATED = 2
+    UNKNOWN = 3
+    INVISIBLE_VISIBILITY = 4
 
-  _VALUES_TO_NAMES = {
-    0: "MINOR",
-    1: "MERGE",
-    2: "MAJOR",
-    3: "FULL",
-  }
+    _VALUES_TO_NAMES = {
+        0: "ACCEPTED",
+        1: "REJECTED",
+        2: "VIOLATED",
+        3: "UNKNOWN",
+        4: "INVISIBLE_VISIBILITY",
+    }
 
-  _NAMES_TO_VALUES = {
-    "MINOR": 0,
-    "MERGE": 1,
-    "MAJOR": 2,
-    "FULL": 3,
-  }
+    _NAMES_TO_VALUES = {
+        "ACCEPTED": 0,
+        "REJECTED": 1,
+        "VIOLATED": 2,
+        "UNKNOWN": 3,
+        "INVISIBLE_VISIBILITY": 4,
+    }
 
-class CompactionReason:
-  USER = 0
-  SYSTEM = 1
-  CHOP = 2
-  IDLE = 3
-  CLOSE = 4
 
-  _VALUES_TO_NAMES = {
-    0: "USER",
-    1: "SYSTEM",
-    2: "CHOP",
-    3: "IDLE",
-    4: "CLOSE",
-  }
+class Durability(object):
+    DEFAULT = 0
+    NONE = 1
+    LOG = 2
+    FLUSH = 3
+    SYNC = 4
 
-  _NAMES_TO_VALUES = {
-    "USER": 0,
-    "SYSTEM": 1,
-    "CHOP": 2,
-    "IDLE": 3,
-    "CLOSE": 4,
-  }
+    _VALUES_TO_NAMES = {
+        0: "DEFAULT",
+        1: "NONE",
+        2: "LOG",
+        3: "FLUSH",
+        4: "SYNC",
+    }
 
-class IteratorScope:
-  MINC = 0
-  MAJC = 1
-  SCAN = 2
+    _NAMES_TO_VALUES = {
+        "DEFAULT": 0,
+        "NONE": 1,
+        "LOG": 2,
+        "FLUSH": 3,
+        "SYNC": 4,
+    }
 
-  _VALUES_TO_NAMES = {
-    0: "MINC",
-    1: "MAJC",
-    2: "SCAN",
-  }
 
-  _NAMES_TO_VALUES = {
-    "MINC": 0,
-    "MAJC": 1,
-    "SCAN": 2,
-  }
+class CompactionType(object):
+    MINOR = 0
+    MERGE = 1
+    MAJOR = 2
+    FULL = 3
 
-class TimeType:
-  LOGICAL = 0
-  MILLIS = 1
+    _VALUES_TO_NAMES = {
+        0: "MINOR",
+        1: "MERGE",
+        2: "MAJOR",
+        3: "FULL",
+    }
 
-  _VALUES_TO_NAMES = {
-    0: "LOGICAL",
-    1: "MILLIS",
-  }
+    _NAMES_TO_VALUES = {
+        "MINOR": 0,
+        "MERGE": 1,
+        "MAJOR": 2,
+        "FULL": 3,
+    }
 
-  _NAMES_TO_VALUES = {
-    "LOGICAL": 0,
-    "MILLIS": 1,
-  }
 
+class CompactionReason(object):
+    USER = 0
+    SYSTEM = 1
+    CHOP = 2
+    IDLE = 3
+    CLOSE = 4
 
-class Key:
-  """
-  Attributes:
-   - row
-   - colFamily
-   - colQualifier
-   - colVisibility
-   - timestamp
-  """
+    _VALUES_TO_NAMES = {
+        0: "USER",
+        1: "SYSTEM",
+        2: "CHOP",
+        3: "IDLE",
+        4: "CLOSE",
+    }
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'row', None, None, ), # 1
-    (2, TType.STRING, 'colFamily', None, None, ), # 2
-    (3, TType.STRING, 'colQualifier', None, None, ), # 3
-    (4, TType.STRING, 'colVisibility', None, None, ), # 4
-    (5, TType.I64, 'timestamp', None, 9223372036854775807, ), # 5
-  )
+    _NAMES_TO_VALUES = {
+        "USER": 0,
+        "SYSTEM": 1,
+        "CHOP": 2,
+        "IDLE": 3,
+        "CLOSE": 4,
+    }
 
-  def __init__(self, row=None, colFamily=None, colQualifier=None, colVisibility=None, timestamp=thrift_spec[5][4],):
-    self.row = row
-    self.colFamily = colFamily
-    self.colQualifier = colQualifier
-    self.colVisibility = colVisibility
-    self.timestamp = timestamp
 
-  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.row = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRING:
-          self.colFamily = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.colQualifier = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRING:
-          self.colVisibility = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.I64:
-          self.timestamp = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+class IteratorScope(object):
+    MINC = 0
+    MAJC = 1
+    SCAN = 2
 
-  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('Key')
-    if self.row is not None:
-      oprot.writeFieldBegin('row', TType.STRING, 1)
-      oprot.writeString(self.row)
-      oprot.writeFieldEnd()
-    if self.colFamily is not None:
-      oprot.writeFieldBegin('colFamily', TType.STRING, 2)
-      oprot.writeString(self.colFamily)
-      oprot.writeFieldEnd()
-    if self.colQualifier is not None:
-      oprot.writeFieldBegin('colQualifier', TType.STRING, 3)
-      oprot.writeString(self.colQualifier)
-      oprot.writeFieldEnd()
-    if self.colVisibility is not None:
-      oprot.writeFieldBegin('colVisibility', TType.STRING, 4)
-      oprot.writeString(self.colVisibility)
-      oprot.writeFieldEnd()
-    if self.timestamp is not None:
-      oprot.writeFieldBegin('timestamp', TType.I64, 5)
-      oprot.writeI64(self.timestamp)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    _VALUES_TO_NAMES = {
+        0: "MINC",
+        1: "MAJC",
+        2: "SCAN",
+    }
 
-  def validate(self):
-    return
+    _NAMES_TO_VALUES = {
+        "MINC": 0,
+        "MAJC": 1,
+        "SCAN": 2,
+    }
 
 
-  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
+class TimeType(object):
+    LOGICAL = 0
+    MILLIS = 1
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    _VALUES_TO_NAMES = {
+        0: "LOGICAL",
+        1: "MILLIS",
+    }
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    _NAMES_TO_VALUES = {
+        "LOGICAL": 0,
+        "MILLIS": 1,
+    }
 
-  def __ne__(self, other):
-    return not (self == other)
 
-class ColumnUpdate:
-  """
-  Attributes:
-   - colFamily
-   - colQualifier
-   - colVisibility
-   - timestamp
-   - value
-   - deleteCell
-  """
+class Key(object):
+    """
+    Attributes:
+     - row
+     - colFamily
+     - colQualifier
+     - colVisibility
+     - timestamp
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'colFamily', None, None, ), # 1
-    (2, TType.STRING, 'colQualifier', None, None, ), # 2
-    (3, TType.STRING, 'colVisibility', None, None, ), # 3
-    (4, TType.I64, 'timestamp', None, None, ), # 4
-    (5, TType.STRING, 'value', None, None, ), # 5
-    (6, TType.BOOL, 'deleteCell', None, None, ), # 6
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'row', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'colFamily', 'BINARY', None, ),  # 2
+        (3, TType.STRING, 'colQualifier', 'BINARY', None, ),  # 3
+        (4, TType.STRING, 'colVisibility', 'BINARY', None, ),  # 4
+        (5, TType.I64, 'timestamp', None, 9223372036854775807, ),  # 5
+    )
 
-  def __init__(self, colFamily=None, colQualifier=None, colVisibility=None, timestamp=None, value=None, deleteCell=None,):
-    self.colFamily = colFamily
-    self.colQualifier = colQualifier
-    self.colVisibility = colVisibility
-    self.timestamp = timestamp
-    self.value = value
-    self.deleteCell = deleteCell
+    def __init__(self, row=None, colFamily=None, colQualifier=None, colVisibility=None, timestamp=thrift_spec[5][4],):
+        self.row = row
+        self.colFamily = colFamily
+        self.colQualifier = colQualifier
+        self.colVisibility = colVisibility
+        self.timestamp = timestamp
 
-  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.colFamily = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRING:
-          self.colQualifier = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.colVisibility = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.I64:
-          self.timestamp = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.STRING:
-          self.value = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 6:
-        if ftype == TType.BOOL:
-          self.deleteCell = iprot.readBool()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.row = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.colFamily = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.colQualifier = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.colVisibility = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.I64:
+                    self.timestamp = iprot.readI64()
+                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('ColumnUpdate')
-    if self.colFamily is not None:
-      oprot.writeFieldBegin('colFamily', TType.STRING, 1)
-      oprot.writeString(self.colFamily)
-      oprot.writeFieldEnd()
-    if self.colQualifier is not None:
-      oprot.writeFieldBegin('colQualifier', TType.STRING, 2)
-      oprot.writeString(self.colQualifier)
-      oprot.writeFieldEnd()
-    if self.colVisibility is not None:
-      oprot.writeFieldBegin('colVisibility', TType.STRING, 3)
-      oprot.writeString(self.colVisibility)
-      oprot.writeFieldEnd()
-    if self.timestamp is not None:
-      oprot.writeFieldBegin('timestamp', TType.I64, 4)
-      oprot.writeI64(self.timestamp)
-      oprot.writeFieldEnd()
-    if self.value is not None:
-      oprot.writeFieldBegin('value', TType.STRING, 5)
-      oprot.writeString(self.value)
-      oprot.writeFieldEnd()
-    if self.deleteCell is not None:
-      oprot.writeFieldBegin('deleteCell', TType.BOOL, 6)
-      oprot.writeBool(self.deleteCell)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('Key')
+        if self.row is not None:
+            oprot.writeFieldBegin('row', TType.STRING, 1)
+            oprot.writeBinary(self.row)
+            oprot.writeFieldEnd()
+        if self.colFamily is not None:
+            oprot.writeFieldBegin('colFamily', TType.STRING, 2)
+            oprot.writeBinary(self.colFamily)
+            oprot.writeFieldEnd()
+        if self.colQualifier is not None:
+            oprot.writeFieldBegin('colQualifier', TType.STRING, 3)
+            oprot.writeBinary(self.colQualifier)
+            oprot.writeFieldEnd()
+        if self.colVisibility is not None:
+            oprot.writeFieldBegin('colVisibility', TType.STRING, 4)
+            oprot.writeBinary(self.colVisibility)
+            oprot.writeFieldEnd()
+        if self.timestamp is not None:
+            oprot.writeFieldBegin('timestamp', TType.I64, 5)
+            oprot.writeI64(self.timestamp)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  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 __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __ne__(self, other):
-    return not (self == other)
+class ColumnUpdate(object):
+    """
+    Attributes:
+     - colFamily
+     - colQualifier
+     - colVisibility
+     - timestamp
+     - value
+     - deleteCell
+    """
 
-class DiskUsage:
-  """
-  Attributes:
-   - tables
-   - usage
-  """
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'colFamily', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'colQualifier', 'BINARY', None, ),  # 2
+        (3, TType.STRING, 'colVisibility', 'BINARY', None, ),  # 3
+        (4, TType.I64, 'timestamp', None, None, ),  # 4
+        (5, TType.STRING, 'value', 'BINARY', None, ),  # 5
+        (6, TType.BOOL, 'deleteCell', None, None, ),  # 6
+    )
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.LIST, 'tables', (TType.STRING,None), None, ), # 1
-    (2, TType.I64, 'usage', None, None, ), # 2
-  )
+    def __init__(self, colFamily=None, colQualifier=None, colVisibility=None, timestamp=None, value=None, deleteCell=None,):
+        self.colFamily = colFamily
+        self.colQualifier = colQualifier
+        self.colVisibility = colVisibility
+        self.timestamp = timestamp
+        self.value = value
+        self.deleteCell = deleteCell
 
-  def __init__(self, tables=None, usage=None,):
-    self.tables = tables
-    self.usage = usage
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.colFamily = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.colQualifier = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.colVisibility = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.I64:
+                    self.timestamp = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.STRING:
+                    self.value = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 6:
+                if ftype == TType.BOOL:
+                    self.deleteCell = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  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.LIST:
-          self.tables = []
-          (_etype3, _size0) = iprot.readListBegin()
-          for _i4 in xrange(_size0):
-            _elem5 = iprot.readString()
-            self.tables.append(_elem5)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.I64:
-          self.usage = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('ColumnUpdate')
+        if self.colFamily is not None:
+            oprot.writeFieldBegin('colFamily', TType.STRING, 1)
+            oprot.writeBinary(self.colFamily)
+            oprot.writeFieldEnd()
+        if self.colQualifier is not None:
+            oprot.writeFieldBegin('colQualifier', TType.STRING, 2)
+            oprot.writeBinary(self.colQualifier)
+            oprot.writeFieldEnd()
+        if self.colVisibility is not None:
+            oprot.writeFieldBegin('colVisibility', TType.STRING, 3)
+            oprot.writeBinary(self.colVisibility)
+            oprot.writeFieldEnd()
+        if self.timestamp is not None:
+            oprot.writeFieldBegin('timestamp', TType.I64, 4)
+            oprot.writeI64(self.timestamp)
+            oprot.writeFieldEnd()
+        if self.value is not None:
+            oprot.writeFieldBegin('value', TType.STRING, 5)
+            oprot.writeBinary(self.value)
+            oprot.writeFieldEnd()
+        if self.deleteCell is not None:
+            oprot.writeFieldBegin('deleteCell', TType.BOOL, 6)
+            oprot.writeBool(self.deleteCell)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  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('DiskUsage')
-    if self.tables is not None:
-      oprot.writeFieldBegin('tables', TType.LIST, 1)
-      oprot.writeListBegin(TType.STRING, len(self.tables))
-      for iter6 in self.tables:
-        oprot.writeString(iter6)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.usage is not None:
-      oprot.writeFieldBegin('usage', TType.I64, 2)
-      oprot.writeI64(self.usage)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def validate(self):
+        return
 
-  def validate(self):
-    return
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.tables)
-    value = (value * 31) ^ hash(self.usage)
-    return value
+    def __ne__(self, other):
+        return not (self == other)
 
-  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__
+class DiskUsage(object):
+    """
+    Attributes:
+     - tables
+     - usage
+    """
 
-  def __ne__(self, other):
-    return not (self == other)
+    thrift_spec = (
+        None,  # 0
+        (1, TType.LIST, 'tables', (TType.STRING, 'UTF8', False), None, ),  # 1
+        (2, TType.I64, 'usage', None, None, ),  # 2
+    )
 
-class KeyValue:
-  """
-  Attributes:
-   - key
-   - value
-  """
+    def __init__(self, tables=None, usage=None,):
+        self.tables = tables
+        self.usage = usage
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'key', (Key, Key.thrift_spec), None, ), # 1
-    (2, TType.STRING, 'value', None, None, ), # 2
-  )
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.LIST:
+                    self.tables = []
+                    (_etype3, _size0) = iprot.readListBegin()
+                    for _i4 in range(_size0):
+                        _elem5 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.tables.append(_elem5)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.I64:
+                    self.usage = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  def __init__(self, key=None, value=None,):
-    self.key = key
-    self.value = value
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('DiskUsage')
+        if self.tables is not None:
+            oprot.writeFieldBegin('tables', TType.LIST, 1)
+            oprot.writeListBegin(TType.STRING, len(self.tables))
+            for iter6 in self.tables:
+                oprot.writeString(iter6.encode('utf-8') if sys.version_info[0] == 2 else iter6)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.usage is not None:
+            oprot.writeFieldBegin('usage', TType.I64, 2)
+            oprot.writeI64(self.usage)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  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.key = Key()
-          self.key.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRING:
-          self.value = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def validate(self):
+        return
 
-  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('KeyValue')
-    if self.key is not None:
-      oprot.writeFieldBegin('key', TType.STRUCT, 1)
-      self.key.write(oprot)
-      oprot.writeFieldEnd()
-    if self.value is not None:
-      oprot.writeFieldBegin('value', TType.STRING, 2)
-      oprot.writeString(self.value)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def validate(self):
-    return
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
+    def __ne__(self, other):
+        return not (self == other)
 
-  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()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+class KeyValue(object):
+    """
+    Attributes:
+     - key
+     - value
+    """
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'key', (Key, Key.thrift_spec), None, ),  # 1
+        (2, TType.STRING, 'value', 'BINARY', None, ),  # 2
+    )
 
-  def __ne__(self, other):
-    return not (self == other)
+    def __init__(self, key=None, value=None,):
+        self.key = key
+        self.value = value
 
-class ScanResult:
-  """
-  Attributes:
-   - results
-   - more
-  """
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.key = Key()
+                    self.key.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.value = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.LIST, 'results', (TType.STRUCT,(KeyValue, KeyValue.thrift_spec)), None, ), # 1
-    (2, TType.BOOL, 'more', None, None, ), # 2
-  )
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('KeyValue')
+        if self.key is not None:
+            oprot.writeFieldBegin('key', TType.STRUCT, 1)
+            self.key.write(oprot)
+            oprot.writeFieldEnd()
+        if self.value is not None:
+            oprot.writeFieldBegin('value', TType.STRING, 2)
+            oprot.writeBinary(self.value)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def __init__(self, results=None, more=None,):
-    self.results = results
-    self.more = more
+    def validate(self):
+        return
 
-  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.LIST:
-          self.results = []
-          (_etype10, _size7) = iprot.readListBegin()
-          for _i11 in xrange(_size7):
-            _elem12 = KeyValue()
-            _elem12.read(iprot)
-            self.results.append(_elem12)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.BOOL:
-          self.more = iprot.readBool()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  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('ScanResult')
-    if self.results is not None:
-      oprot.writeFieldBegin('results', TType.LIST, 1)
-      oprot.writeListBegin(TType.STRUCT, len(self.results))
-      for iter13 in self.results:
-        iter13.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.more is not None:
-      oprot.writeFieldBegin('more', TType.BOOL, 2)
-      oprot.writeBool(self.more)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def validate(self):
-    return
+    def __ne__(self, other):
+        return not (self == other)
 
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.results)
-    value = (value * 31) ^ hash(self.more)
-    return value
+class ScanResult(object):
+    """
+    Attributes:
+     - results
+     - more
+    """
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    thrift_spec = (
+        None,  # 0
+        (1, TType.LIST, 'results', (TType.STRUCT, (KeyValue, KeyValue.thrift_spec), False), None, ),  # 1
+        (2, TType.BOOL, 'more', None, None, ),  # 2
+    )
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def __init__(self, results=None, more=None,):
+        self.results = results
+        self.more = more
 
-  def __ne__(self, other):
-    return not (self == other)
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.LIST:
+                    self.results = []
+                    (_etype10, _size7) = iprot.readListBegin()
+                    for _i11 in range(_size7):
+                        _elem12 = KeyValue()
+                        _elem12.read(iprot)
+                        self.results.append(_elem12)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.BOOL:
+                    self.more = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-class Range:
-  """
-  Attributes:
-   - start
-   - startInclusive
-   - stop
-   - stopInclusive
-  """
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('ScanResult')
+        if self.results is not None:
+            oprot.writeFieldBegin('results', TType.LIST, 1)
+            oprot.writeListBegin(TType.STRUCT, len(self.results))
+            for iter13 in self.results:
+                iter13.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.more is not None:
+            oprot.writeFieldBegin('more', TType.BOOL, 2)
+            oprot.writeBool(self.more)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'start', (Key, Key.thrift_spec), None, ), # 1
-    (2, TType.BOOL, 'startInclusive', None, None, ), # 2
-    (3, TType.STRUCT, 'stop', (Key, Key.thrift_spec), None, ), # 3
-    (4, TType.BOOL, 'stopInclusive', None, None, ), # 4
-  )
+    def validate(self):
+        return
 
-  def __init__(self, start=None, startInclusive=None, stop=None, stopInclusive=None,):
-    self.start = start
-    self.startInclusive = startInclusive
-    self.stop = stop
-    self.stopInclusive = stopInclusive
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  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.start = Key()
-          self.start.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.BOOL:
-          self.startInclusive = iprot.readBool()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRUCT:
-          self.stop = Key()
-          self.stop.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.BOOL:
-          self.stopInclusive = iprot.readBool()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  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('Range')
-    if self.start is not None:
-      oprot.writeFieldBegin('start', TType.STRUCT, 1)
-      self.start.write(oprot)
-      oprot.writeFieldEnd()
-    if self.startInclusive is not None:
-      oprot.writeFieldBegin('startInclusive', TType.BOOL, 2)
-      oprot.writeBool(self.startInclusive)
-      oprot.writeFieldEnd()
-    if self.stop is not None:
-      oprot.writeFieldBegin('stop', TType.STRUCT, 3)
-      self.stop.write(oprot)
-      oprot.writeFieldEnd()
-    if self.stopInclusive is not None:
-      oprot.writeFieldBegin('stopInclusive', TType.BOOL, 4)
-      oprot.writeBool(self.stopInclusive)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def __ne__(self, other):
+        return not (self == other)
 
-  def validate(self):
-    return
 
+class Range(object):
+    """
+    Attributes:
+     - start
+     - startInclusive
+     - stop
+     - stopInclusive
+    """
 
-  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
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'start', (Key, Key.thrift_spec), None, ),  # 1
+        (2, TType.BOOL, 'startInclusive', None, None, ),  # 2
+        (3, TType.STRUCT, 'stop', (Key, Key.thrift_spec), None, ),  # 3
+        (4, TType.BOOL, 'stopInclusive', None, None, ),  # 4
+    )
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __init__(self, start=None, startInclusive=None, stop=None, stopInclusive=None,):
+        self.start = start
+        self.startInclusive = startInclusive
+        self.stop = stop
+        self.stopInclusive = stopInclusive
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.start = Key()
+                    self.start.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.BOOL:
+                    self.startInclusive = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRUCT:
+                    self.stop = Key()
+                    self.stop.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.BOOL:
+                    self.stopInclusive = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  def __ne__(self, other):
-    return not (self == other)
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('Range')
+        if self.start is not None:
+            oprot.writeFieldBegin('start', TType.STRUCT, 1)
+            self.start.write(oprot)
+            oprot.writeFieldEnd()
+        if self.startInclusive is not None:
+            oprot.writeFieldBegin('startInclusive', TType.BOOL, 2)
+            oprot.writeBool(self.startInclusive)
+            oprot.writeFieldEnd()
+        if self.stop is not None:
+            oprot.writeFieldBegin('stop', TType.STRUCT, 3)
+            self.stop.write(oprot)
+            oprot.writeFieldEnd()
+        if self.stopInclusive is not None:
+            oprot.writeFieldBegin('stopInclusive', TType.BOOL, 4)
+            oprot.writeBool(self.stopInclusive)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-class ScanColumn:
-  """
-  Attributes:
-   - colFamily
-   - colQualifier
-  """
+    def validate(self):
+        return
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'colFamily', None, None, ), # 1
-    (2, TType.STRING, 'colQualifier', None, None, ), # 2
-  )
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __init__(self, colFamily=None, colQualifier=None,):
-    self.colFamily = colFamily
-    self.colQualifier = colQualifier
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  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.colFamily = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRING:
-          self.colQualifier = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def __ne__(self, other):
+        return not (self == other)
 
-  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('ScanColumn')
-    if self.colFamily is not None:
-      oprot.writeFieldBegin('colFamily', TType.STRING, 1)
-      oprot.writeString(self.colFamily)
-      oprot.writeFieldEnd()
-    if self.colQualifier is not None:
-      oprot.writeFieldBegin('colQualifier', TType.STRING, 2)
-      oprot.writeString(self.colQualifier)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
 
-  def validate(self):
-    return
+class ScanColumn(object):
+    """
+    Attributes:
+     - colFamily
+     - colQualifier
+    """
 
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'colFamily', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'colQualifier', 'BINARY', None, ),  # 2
+    )
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.colFamily)
-    value = (value * 31) ^ hash(self.colQualifier)
-    return value
+    def __init__(self, colFamily=None, colQualifier=None,):
+        self.colFamily = colFamily
+        self.colQualifier = colQualifier
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.colFamily = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.colQualifier = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('ScanColumn')
+        if self.colFamily is not None:
+            oprot.writeFieldBegin('colFamily', TType.STRING, 1)
+            oprot.writeBinary(self.colFamily)
+            oprot.writeFieldEnd()
+        if self.colQualifier is not None:
+            oprot.writeFieldBegin('colQualifier', TType.STRING, 2)
+            oprot.writeBinary(self.colQualifier)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def __ne__(self, other):
-    return not (self == other)
+    def validate(self):
+        return
 
-class IteratorSetting:
-  """
-  Attributes:
-   - priority
-   - name
-   - iteratorClass
-   - properties
-  """
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.I32, 'priority', None, None, ), # 1
-    (2, TType.STRING, 'name', None, None, ), # 2
-    (3, TType.STRING, 'iteratorClass', None, None, ), # 3
-    (4, TType.MAP, 'properties', (TType.STRING,None,TType.STRING,None), None, ), # 4
-  )
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __init__(self, priority=None, name=None, iteratorClass=None, properties=None,):
-    self.priority = priority
-    self.name = name
-    self.iteratorClass = iteratorClass
-    self.properties = properties
+    def __ne__(self, other):
+        return not (self == other)
 
-  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.I32:
-          self.priority = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRING:
-          self.name = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.iteratorClass = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.MAP:
-          self.properties = {}
-          (_ktype15, _vtype16, _size14 ) = iprot.readMapBegin()
-          for _i18 in xrange(_size14):
-            _key19 = iprot.readString()
-            _val20 = iprot.readString()
-            self.properties[_key19] = _val20
-          iprot.readMapEnd()
-        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('IteratorSetting')
-    if self.priority is not None:
-      oprot.writeFieldBegin('priority', TType.I32, 1)
-      oprot.writeI32(self.priority)
-      oprot.writeFieldEnd()
-    if self.name is not None:
-      oprot.writeFieldBegin('name', TType.STRING, 2)
-      oprot.writeString(self.name)
-      oprot.writeFieldEnd()
-    if self.iteratorClass is not None:
-      oprot.writeFieldBegin('iteratorClass', TType.STRING, 3)
-      oprot.writeString(self.iteratorClass)
-      oprot.writeFieldEnd()
-    if self.properties is not None:
-      oprot.writeFieldBegin('properties', TType.MAP, 4)
-      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.properties))
-      for kiter21,viter22 in self.properties.items():
-        oprot.writeString(kiter21)
-        oprot.writeString(viter22)
-      oprot.writeMapEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+class IteratorSetting(object):
+    """
+    Attributes:
+     - priority
+     - name
+     - iteratorClass
+     - properties
+    """
 
-  def validate(self):
-    return
+    thrift_spec = (
+        None,  # 0
+        (1, TType.I32, 'priority', None, None, ),  # 1
+        (2, TType.STRING, 'name', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'iteratorClass', 'UTF8', None, ),  # 3
+        (4, TType.MAP, 'properties', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), None, ),  # 4
+    )
 
+    def __init__(self, priority=None, name=None, iteratorClass=None, properties=None,):
+        self.priority = priority
+        self.name = name
+        self.iteratorClass = iteratorClass
+        self.properties = properties
 
-  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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.I32:
+                    self.priority = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.name = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.iteratorClass = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.MAP:
+                    self.properties = {}
+                    (_ktype15, _vtype16, _size14) = iprot.readMapBegin()
+                    for _i18 in range(_size14):
+                        _key19 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val20 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.properties[_key19] = _val20
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('IteratorSetting')
+        if self.priority is not None:
+            oprot.writeFieldBegin('priority', TType.I32, 1)
+            oprot.writeI32(self.priority)
+            oprot.writeFieldEnd()
+        if self.name is not None:
+            oprot.writeFieldBegin('name', TType.STRING, 2)
+            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
+            oprot.writeFieldEnd()
+        if self.iteratorClass is not None:
+            oprot.writeFieldBegin('iteratorClass', TType.STRING, 3)
+            oprot.writeString(self.iteratorClass.encode('utf-8') if sys.version_info[0] == 2 else self.iteratorClass)
+            oprot.writeFieldEnd()
+        if self.properties is not None:
+            oprot.writeFieldBegin('properties', TType.MAP, 4)
+            oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.properties))
+            for kiter21, viter22 in self.properties.items():
+                oprot.writeString(kiter21.encode('utf-8') if sys.version_info[0] == 2 else kiter21)
+                oprot.writeString(viter22.encode('utf-8') if sys.version_info[0] == 2 else viter22)
+            oprot.writeMapEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def validate(self):
+        return
 
-  def __ne__(self, other):
-    return not (self == other)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-class ScanOptions:
-  """
-  Attributes:
-   - authorizations
-   - range
-   - columns
-   - iterators
-   - bufferSize
-  """
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.SET, 'authorizations', (TType.STRING,None), None, ), # 1
-    (2, TType.STRUCT, 'range', (Range, Range.thrift_spec), None, ), # 2
-    (3, TType.LIST, 'columns', (TType.STRUCT,(ScanColumn, ScanColumn.thrift_spec)), None, ), # 3
-    (4, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 4
-    (5, TType.I32, 'bufferSize', None, None, ), # 5
-  )
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __init__(self, authorizations=None, range=None, columns=None, iterators=None, bufferSize=None,):
-    self.authorizations = authorizations
-    self.range = range
-    self.columns = columns
-    self.iterators = iterators
-    self.bufferSize = bufferSize
 
-  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.SET:
-          self.authorizations = set()
-          (_etype26, _size23) = iprot.readSetBegin()
-          for _i27 in xrange(_size23):
-            _elem28 = iprot.readString()
-            self.authorizations.add(_elem28)
-          iprot.readSetEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRUCT:
-          self.range = Range()
-          self.range.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.LIST:
-          self.columns = []
-          (_etype32, _size29) = iprot.readListBegin()
-          for _i33 in xrange(_size29):
-            _elem34 = ScanColumn()
-            _elem34.read(iprot)
-            self.columns.append(_elem34)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.LIST:
-          self.iterators = []
-          (_etype38, _size35) = iprot.readListBegin()
-          for _i39 in xrange(_size35):
-            _elem40 = IteratorSetting()
-            _elem40.read(iprot)
-            self.iterators.append(_elem40)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.I32:
-          self.bufferSize = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+class ScanOptions(object):
+    """
+    Attributes:
+     - authorizations
+     - range
+     - columns
+     - iterators
+     - bufferSize
+    """
 
-  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('ScanOptions')
-    if self.authorizations is not None:
-      oprot.writeFieldBegin('authorizations', TType.SET, 1)
-      oprot.writeSetBegin(TType.STRING, len(self.authorizations))
-      for iter41 in self.authorizations:
-        oprot.writeString(iter41)
-      oprot.writeSetEnd()
-      oprot.writeFieldEnd()
-    if self.range is not None:
-      oprot.writeFieldBegin('range', TType.STRUCT, 2)
-      self.range.write(oprot)
-      oprot.writeFieldEnd()
-    if self.columns is not None:
-      oprot.writeFieldBegin('columns', TType.LIST, 3)
-      oprot.writeListBegin(TType.STRUCT, len(self.columns))
-      for iter42 in self.columns:
-        iter42.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.iterators is not None:
-      oprot.writeFieldBegin('iterators', TType.LIST, 4)
-      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
-      for iter43 in self.iterators:
-        iter43.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.bufferSize is not None:
-      oprot.writeFieldBegin('bufferSize', TType.I32, 5)
-      oprot.writeI32(self.bufferSize)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.SET, 'authorizations', (TType.STRING, 'BINARY', False), None, ),  # 1
+        (2, TType.STRUCT, 'range', (Range, Range.thrift_spec), None, ),  # 2
+        (3, TType.LIST, 'columns', (TType.STRUCT, (ScanColumn, ScanColumn.thrift_spec), False), None, ),  # 3
+        (4, TType.LIST, 'iterators', (TType.STRUCT, (IteratorSetting, IteratorSetting.thrift_spec), False), None, ),  # 4
+        (5, TType.I32, 'bufferSize', None, None, ),  # 5
+    )
 
-  def validate(self):
-    return
+    def __init__(self, authorizations=None, range=None, columns=None, iterators=None, bufferSize=None,):
+        self.authorizations = authorizations
+        self.range = range
+        self.columns = columns
+        self.iterators = iterators
+        self.bufferSize = bufferSize
 
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.SET:
+                    self.authorizations = set()
+                    (_etype26, _size23) = iprot.readSetBegin()
+                    for _i27 in range(_size23):
+                        _elem28 = iprot.readBinary()
+                        self.authorizations.add(_elem28)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRUCT:
+                    self.range = Range()
+                    self.range.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.LIST:
+                    self.columns = []
+                    (_etype32, _size29) = iprot.readListBegin()
+                    for _i33 in range(_size29):
+                        _elem34 = ScanColumn()
+                        _elem34.read(iprot)
+                        self.columns.append(_elem34)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.LIST:
+                    self.iterators = []
+                    (_etype38, _size35) = iprot.readListBegin()
+                    for _i39 in range(_size35):
+                        _elem40 = IteratorSetting()
+                        _elem40.read(iprot)
+                        self.iterators.append(_elem40)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.I32:
+                    self.bufferSize = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  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 write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('ScanOptions')
+        if self.authorizations is not None:
+            oprot.writeFieldBegin('authorizations', TType.SET, 1)
+            oprot.writeSetBegin(TType.STRING, len(self.authorizations))
+            for iter41 in self.authorizations:
+                oprot.writeBinary(iter41)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        if self.range is not None:
+            oprot.writeFieldBegin('range', TType.STRUCT, 2)
+            self.range.write(oprot)
+            oprot.writeFieldEnd()
+        if self.columns is not None:
+            oprot.writeFieldBegin('columns', TType.LIST, 3)
+            oprot.writeListBegin(TType.STRUCT, len(self.columns))
+            for iter42 in self.columns:
+                iter42.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.iterators is not None:
+            oprot.writeFieldBegin('iterators', TType.LIST, 4)
+            oprot.writeListBegin(TType.STRUCT, len(self.iterators))
+            for iter43 in self.iterators:
+                iter43.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.bufferSize is not None:
+            oprot.writeFieldBegin('bufferSize', TType.I32, 5)
+            oprot.writeI32(self.bufferSize)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def validate(self):
+        return
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __ne__(self, other):
-    return not (self == other)
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-class BatchScanOptions:
-  """
-  Attributes:
-   - authorizations
-   - ranges
-   - columns
-   - iterators
-   - threads
-  """
+    def __ne__(self, other):
+        return not (self == other)
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.SET, 'authorizations', (TType.STRING,None), None, ), # 1
-    (2, TType.LIST, 'ranges', (TType.STRUCT,(Range, Range.thrift_spec)), None, ), # 2
-    (3, TType.LIST, 'columns', (TType.STRUCT,(ScanColumn, ScanColumn.thrift_spec)), None, ), # 3
-    (4, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 4
-    (5, TType.I32, 'threads', None, None, ), # 5
-  )
 
-  def __init__(self, authorizations=None, ranges=None, columns=None, iterators=None, threads=None,):
-    self.authorizations = authorizations
-    self.ranges = ranges
-    self.columns = columns
-    self.iterators = iterators
-    self.threads = threads
+class BatchScanOptions(object):
+    """
+    Attributes:
+     - authorizations
+     - ranges
+     - columns
+     - iterators
+     - threads
+    """
 
-  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.SET:
-          self.authorizations = set()
-          (_etype47, _size44) = iprot.readSetBegin()
-          for _i48 in xrange(_size44):
-            _elem49 = iprot.readString()
-            self.authorizations.add(_elem49)
-          iprot.readSetEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.LIST:
-          self.ranges = []
-          (_etype53, _size50) = iprot.readListBegin()
-          for _i54 in xrange(_size50):
-            _elem55 = Range()
-            _elem55.read(iprot)
-            self.ranges.append(_elem55)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.LIST:
-          self.columns = []
-          (_etype59, _size56) = iprot.readListBegin()
-          for _i60 in xrange(_size56):
-            _elem61 = ScanColumn()
-            _elem61.read(iprot)
-            self.columns.append(_elem61)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.LIST:
-          self.iterators = []
-          (_etype65, _size62) = iprot.readListBegin()
-          for _i66 in xrange(_size62):
-            _elem67 = IteratorSetting()
-            _elem67.read(iprot)
-            self.iterators.append(_elem67)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.I32:
-          self.threads = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.SET, 'authorizations', (TType.STRING, 'BINARY', False), None, ),  # 1
+        (2, TType.LIST, 'ranges', (TType.STRUCT, (Range, Range.thrift_spec), False), None, ),  # 2
+        (3, TType.LIST, 'columns', (TType.STRUCT, (ScanColumn, ScanColumn.thrift_spec), False), None, ),  # 3
+        (4, TType.LIST, 'iterators', (TType.STRUCT, (IteratorSetting, IteratorSetting.thrift_spec), False), None, ),  # 4
+        (5, TType.I32, 'threads', None, None, ),  # 5
+    )
 
-  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('BatchScanOptions')
-    if self.authorizations is not None:
-      oprot.writeFieldBegin('authorizations', TType.SET, 1)
-      oprot.writeSetBegin(TType.STRING, len(self.authorizations))
-      for iter68 in self.authorizations:
-        oprot.writeString(iter68)
-      oprot.writeSetEnd()
-      oprot.writeFieldEnd()
-    if self.ranges is not None:
-      oprot.writeFieldBegin('ranges', TType.LIST, 2)
-      oprot.writeListBegin(TType.STRUCT, len(self.ranges))
-      for iter69 in self.ranges:
-        iter69.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.columns is not None:
-      oprot.writeFieldBegin('columns', TType.LIST, 3)
-      oprot.writeListBegin(TType.STRUCT, len(self.columns))
-      for iter70 in self.columns:
-        iter70.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.iterators is not None:
-      oprot.writeFieldBegin('iterators', TType.LIST, 4)
-      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
-      for iter71 in self.iterators:
-        iter71.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.threads is not None:
-      oprot.writeFieldBegin('threads', TType.I32, 5)
-      oprot.writeI32(self.threads)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def __init__(self, authorizations=None, ranges=None, columns=None, iterators=None, threads=None,):
+        self.authorizations = authorizations
+        self.ranges = ranges
+        self.columns = columns
+        self.iterators = iterators
+        self.threads = threads
 
-  def validate(self):
-    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()]
-    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 KeyValueAndPeek:
-  """
-  Attributes:
-   - keyValue
-   - hasNext
-  """
-
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'keyValue', (KeyValue, KeyValue.thrift_spec), None, ), # 1
-    (2, TType.BOOL, 'hasNext', None, None, ), # 2
-  )
-
-  def __init__(self, keyValue=None, hasNext=None,):
-    self.keyValue = keyValue
-    self.hasNext = hasNext
-
-  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.keyValue = KeyValue()
-          self.keyValue.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.BOOL:
-          self.hasNext = iprot.readBool()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.SET:
+                    self.authorizations = set()
+                    (_etype47, _size44) = iprot.readSetBegin()
+                    for _i48 in range(_size44):
+                        _elem49 = iprot.readBinary()
+                        self.authorizations.add(_elem49)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.LIST:
+                    self.ranges = []
+                    (_etype53, _size50) = iprot.readListBegin()
+                    for _i54 in range(_size50):
+                        _elem55 = Range()
+                        _elem55.read(iprot)
+                        self.ranges.append(_elem55)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.LIST:
+                    self.columns = []
+                    (_etype59, _size56) = iprot.readListBegin()
+                    for _i60 in range(_size56):
+                        _elem61 = ScanColumn()
+                        _elem61.read(iprot)
+                        self.columns.append(_elem61)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.LIST:
+                    self.iterators = []
+                    (_etype65, _size62) = iprot.readListBegin()
+                    for _i66 in range(_size62):
+                        _elem67 = IteratorSetting()
+                        _elem67.read(iprot)
+                        self.iterators.append(_elem67)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.I32:
+                    self.threads = 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('KeyValueAndPeek')
-    if self.keyValue is not None:
-      oprot.writeFieldBegin('keyValue', TType.STRUCT, 1)
-      self.keyValue.write(oprot)
-      oprot.writeFieldEnd()
-    if self.hasNext is not None:
-      oprot.writeFieldBegin('hasNext', TType.BOOL, 2)
-      oprot.writeBool(self.hasNext)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('BatchScanOptions')
+        if self.authorizations is not None:
+            oprot.writeFieldBegin('authorizations', TType.SET, 1)
+            oprot.writeSetBegin(TType.STRING, len(self.authorizations))
+            for iter68 in self.authorizations:
+                oprot.writeBinary(iter68)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        if self.ranges is not None:
+            oprot.writeFieldBegin('ranges', TType.LIST, 2)
+            oprot.writeListBegin(TType.STRUCT, len(self.ranges))
+            for iter69 in self.ranges:
+                iter69.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.columns is not None:
+            oprot.writeFieldBegin('columns', TType.LIST, 3)
+            oprot.writeListBegin(TType.STRUCT, len(self.columns))
+            for iter70 in self.columns:
+                iter70.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.iterators is not None:
+            oprot.writeFieldBegin('iterators', TType.LIST, 4)
+            oprot.writeListBegin(TType.STRUCT, len(self.iterators))
+            for iter71 in self.iterators:
+                iter71.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.threads is not None:
+            oprot.writeFieldBegin('threads', TType.I32, 5)
+            oprot.writeI32(self.threads)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.keyValue)
-    value = (value * 31) ^ hash(self.hasNext)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __ne__(self, other):
-    return not (self == other)
+class KeyValueAndPeek(object):
+    """
+    Attributes:
+     - keyValue
+     - hasNext
+    """
 
-class KeyExtent:
-  """
-  Attributes:
-   - tableId
-   - endRow
-   - prevEndRow
-  """
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'keyValue', (KeyValue, KeyValue.thrift_spec), None, ),  # 1
+        (2, TType.BOOL, 'hasNext', None, None, ),  # 2
+    )
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'tableId', None, None, ), # 1
-    (2, TType.STRING, 'endRow', None, None, ), # 2
-    (3, TType.STRING, 'prevEndRow', None, None, ), # 3
-  )
+    def __init__(self, keyValue=None, hasNext=None,):
+        self.keyValue = keyValue
+        self.hasNext = hasNext
 
-  def __init__(self, tableId=None, endRow=None, prevEndRow=None,):
-    self.tableId = tableId
-    self.endRow = endRow
-    self.prevEndRow = prevEndRow
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.keyValue = KeyValue()
+                    self.keyValue.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.BOOL:
+                    self.hasNext = iprot.readBool()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  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.tableId = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRING:
-          self.endRow = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.prevEndRow = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('KeyValueAndPeek')
+        if self.keyValue is not None:
+            oprot.writeFieldBegin('keyValue', TType.STRUCT, 1)
+            self.keyValue.write(oprot)
+            oprot.writeFieldEnd()
+        if self.hasNext is not None:
+            oprot.writeFieldBegin('hasNext', TType.BOOL, 2)
+            oprot.writeBool(self.hasNext)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  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('KeyExtent')
-    if self.tableId is not None:
-      oprot.writeFieldBegin('tableId', TType.STRING, 1)
-      oprot.writeString(self.tableId)
-      oprot.writeFieldEnd()
-    if self.endRow is not None:
-      oprot.writeFieldBegin('endRow', TType.STRING, 2)
-      oprot.writeString(self.endRow)
-      oprot.writeFieldEnd()
-    if self.prevEndRow is not None:
-      oprot.writeFieldBegin('prevEndRow', TType.STRING, 3)
-      oprot.writeString(self.prevEndRow)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def validate(self):
+        return
 
-  def validate(self):
-    return
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  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 __ne__(self, other):
+        return not (self == other)
 
-  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__
+class KeyExtent(object):
+    """
+    Attributes:
+     - tableId
+     - endRow
+     - prevEndRow
+    """
 
-  def __ne__(self, other):
-    return not (self == other)
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'tableId', 'UTF8', None, ),  # 1
+        (2, TType.STRING, 'endRow', 'BINARY', None, ),  # 2
+        (3, TType.STRING, 'prevEndRow', 'BINARY', None, ),  # 3
+    )
 
-class Column:
-  """
-  Attributes:
-   - colFamily
-   - colQualifier
-   - colVisibility
-  """
+    def __init__(self, tableId=None, endRow=None, prevEndRow=None,):
+        self.tableId = tableId
+        self.endRow = endRow
+        self.prevEndRow = prevEndRow
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'colFamily', None, None, ), # 1
-    (2, TType.STRING, 'colQualifier', None, None, ), # 2
-    (3, TType.STRING, 'colVisibility', None, None, ), # 3
-  )
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.tableId = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.endRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.prevEndRow = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  def __init__(self, colFamily=None, colQualifier=None, colVisibility=None,):
-    self.colFamily = colFamily
-    self.colQualifier = colQualifier
-    self.colVisibility = colVisibility
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('KeyExtent')
+        if self.tableId is not None:
+            oprot.writeFieldBegin('tableId', TType.STRING, 1)
+            oprot.writeString(self.tableId.encode('utf-8') if sys.version_info[0] == 2 else self.tableId)
+            oprot.writeFieldEnd()
+        if self.endRow is not None:
+            oprot.writeFieldBegin('endRow', TType.STRING, 2)
+            oprot.writeBinary(self.endRow)
+            oprot.writeFieldEnd()
+        if self.prevEndRow is not None:
+            oprot.writeFieldBegin('prevEndRow', TType.STRING, 3)
+            oprot.writeBinary(self.prevEndRow)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  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.colFamily = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.STRING:
-          self.colQualifier = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.colVisibility = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def validate(self):
+        return
 
-  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('Column')
-    if self.colFamily is not None:
-      oprot.writeFieldBegin('colFamily', TType.STRING, 1)
-      oprot.writeString(self.colFamily)
-      oprot.writeFieldEnd()
-    if self.colQualifier is not None:
-      oprot.writeFieldBegin('colQualifier', TType.STRING, 2)
-      oprot.writeString(self.colQualifier)
-      oprot.writeFieldEnd()
-    if self.colVisibility is not None:
-      oprot.writeFieldBegin('colVisibility', TType.STRING, 3)
-      oprot.writeString(self.colVisibility)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def validate(self):
-    return
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
+    def __ne__(self, other):
+        return not (self == other)
 
-  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()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+class Column(object):
+    """
+    Attributes:
+     - colFamily
+     - colQualifier
+     - colVisibility
+    """
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'colFamily', 'BINARY', None, ),  # 1
+        (2, TType.STRING, 'colQualifier', 'BINARY', None, ),  # 2
+        (3, TType.STRING, 'colVisibility', 'BINARY', None, ),  # 3
+    )
 
-  def __ne__(self, other):
-    return not (self == other)
+    def __init__(self, colFamily=None, colQualifier=None, colVisibility=None,):
+        self.colFamily = colFamily
+        self.colQualifier = colQualifier
+        self.colVisibility = colVisibility
 
-class Condition:
-  """
-  Attributes:
-   - column
-   - timestamp
-   - value
-   - iterators
-  """
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.colFamily = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.colQualifier = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.colVisibility = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'column', (Column, Column.thrift_spec), None, ), # 1
-    (2, TType.I64, 'timestamp', None, None, ), # 2
-    (3, TType.STRING, 'value', None, None, ), # 3
-    (4, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 4
-  )
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('Column')
+        if self.colFamily is not None:
+            oprot.writeFieldBegin('colFamily', TType.STRING, 1)
+            oprot.writeBinary(self.colFamily)
+            oprot.writeFieldEnd()
+        if self.colQualifier is not None:
+            oprot.writeFieldBegin('colQualifier', TType.STRING, 2)
+            oprot.writeBinary(self.colQualifier)
+            oprot.writeFieldEnd()
+        if self.colVisibility is not None:
+            oprot.writeFieldBegin('colVisibility', TType.STRING, 3)
+            oprot.writeBinary(self.colVisibility)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def __init__(self, column=None, timestamp=None, value=None, iterators=None,):
-    self.column = column
-    self.timestamp = timestamp
-    self.value = value
-    self.iterators = iterators
+    def validate(self):
+        return
 
-  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.column = Column()
-          self.column.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.I64:
-          self.timestamp = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.STRING:
-          self.value = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.LIST:
-          self.iterators = []
-          (_etype75, _size72) = iprot.readListBegin()
-          for _i76 in xrange(_size72):
-            _elem77 = IteratorSetting()
-            _elem77.read(iprot)
-            self.iterators.append(_elem77)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  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('Condition')
-    if self.column is not None:
-      oprot.writeFieldBegin('column', TType.STRUCT, 1)
-      self.column.write(oprot)
-      oprot.writeFieldEnd()
-    if self.timestamp is not None:
-      oprot.writeFieldBegin('timestamp', TType.I64, 2)
-      oprot.writeI64(self.timestamp)
-      oprot.writeFieldEnd()
-    if self.value is not None:
-      oprot.writeFieldBegin('value', TType.STRING, 3)
-      oprot.writeString(self.value)
-      oprot.writeFieldEnd()
-    if self.iterators is not None:
-      oprot.writeFieldBegin('iterators', TType.LIST, 4)
-      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
-      for iter78 in self.iterators:
-        iter78.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def validate(self):
-    return
+    def __ne__(self, other):
+        return not (self == other)
 
 
-  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
+class Condition(object):
+    """
+    Attributes:
+     - column
+     - timestamp
+     - value
+     - iterators
+    """
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'column', (Column, Column.thrift_spec), None, ),  # 1
+        (2, TType.I64, 'timestamp', None, None, ),  # 2
+        (3, TType.STRING, 'value', 'BINARY', None, ),  # 3
+        (4, TType.LIST, 'iterators', (TType.STRUCT, (IteratorSetting, IteratorSetting.thrift_spec), False), None, ),  # 4
+    )
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def __init__(self, column=None, timestamp=None, value=None, iterators=None,):
+        self.column = column
+        self.timestamp = timestamp
+        self.value = value
+        self.iterators = iterators
 
-  def __ne__(self, other):
-    return not (self == other)
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.column = Column()
+                    self.column.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.I64:
+                    self.timestamp = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.value = iprot.readBinary()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.LIST:
+                    self.iterators = []
+                    (_etype75, _size72) = iprot.readListBegin()
+                    for _i76 in range(_size72):
+                        _elem77 = IteratorSetting()
+                        _elem77.read(iprot)
+                        self.iterators.append(_elem77)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-class ConditionalUpdates:
-  """
-  Attributes:
-   - conditions
-   - updates
-  """
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('Condition')
+        if self.column is not None:
+            oprot.writeFieldBegin('column', TType.STRUCT, 1)
+            self.column.write(oprot)
+            oprot.writeFieldEnd()
+        if self.timestamp is not None:
+            oprot.writeFieldBegin('timestamp', TType.I64, 2)
+            oprot.writeI64(self.timestamp)
+            oprot.writeFieldEnd()
+        if self.value is not None:
+            oprot.writeFieldBegin('value', TType.STRING, 3)
+            oprot.writeBinary(self.value)
+            oprot.writeFieldEnd()
+        if self.iterators is not None:
+            oprot.writeFieldBegin('iterators', TType.LIST, 4)
+            oprot.writeListBegin(TType.STRUCT, len(self.iterators))
+            for iter78 in self.iterators:
+                iter78.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  thrift_spec = (
-    None, # 0
-    None, # 1
-    (2, TType.LIST, 'conditions', (TType.STRUCT,(Condition, Condition.thrift_spec)), None, ), # 2
-    (3, TType.LIST, 'updates', (TType.STRUCT,(ColumnUpdate, ColumnUpdate.thrift_spec)), None, ), # 3
-  )
+    def validate(self):
+        return
 
-  def __init__(self, conditions=None, updates=None,):
-    self.conditions = conditions
-    self.updates = updates
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  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 == 2:
-        if ftype == TType.LIST:
-          self.conditions = []
-          (_etype82, _size79) = iprot.readListBegin()
-          for _i83 in xrange(_size79):
-            _elem84 = Condition()
-            _elem84.read(iprot)
-            self.conditions.append(_elem84)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.LIST:
-          self.updates = []
-          (_etype88, _size85) = iprot.readListBegin()
-          for _i89 in xrange(_size85):
-            _elem90 = ColumnUpdate()
-            _elem90.read(iprot)
-            self.updates.append(_elem90)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  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('ConditionalUpdates')
-    if self.conditions is not None:
-      oprot.writeFieldBegin('conditions', TType.LIST, 2)
-      oprot.writeListBegin(TType.STRUCT, len(self.conditions))
-      for iter91 in self.conditions:
-        iter91.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.updates is not None:
-      oprot.writeFieldBegin('updates', TType.LIST, 3)
-      oprot.writeListBegin(TType.STRUCT, len(self.updates))
-      for iter92 in self.updates:
-        iter92.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def __ne__(self, other):
+        return not (self == other)
 
-  def validate(self):
-    return
 
+class ConditionalUpdates(object):
+    """
+    Attributes:
+     - conditions
+     - updates
+    """
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.conditions)
-    value = (value * 31) ^ hash(self.updates)
-    return value
+    thrift_spec = (
+        None,  # 0
+        None,  # 1
+        (2, TType.LIST, 'conditions', (TType.STRUCT, (Condition, Condition.thrift_spec), False), None, ),  # 2
+        (3, TType.LIST, 'updates', (TType.STRUCT, (ColumnUpdate, ColumnUpdate.thrift_spec), False), None, ),  # 3
+    )
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __init__(self, conditions=None, updates=None,):
+        self.conditions = conditions
+        self.updates = updates
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
+            return
+        iprot.readStructBegin()
+        while True:
+            (fname, ftype, fid) = iprot.readFieldBegin()
+            if ftype == TType.STOP:
+                break
+            if fid == 2:
+                if ftype == TType.LIST:
+                    self.conditions = []
+                    (_etype82, _size79) = iprot.readListBegin()
+                    for _i83 in range(_size79):
+                        _elem84 = Condition()
+                        _elem84.read(iprot)
+                        self.conditions.append(_elem84)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.LIST:
+                    self.updates = []
+                    (_etype88, _size85) = iprot.readListBegin()
+                    for _i89 in range(_size85):
+                        _elem90 = ColumnUpdate()
+                        _elem90.read(iprot)
+                        self.updates.append(_elem90)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  def __ne__(self, other):
-    return not (self == other)
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('ConditionalUpdates')
+        if self.conditions is not None:
+            oprot.writeFieldBegin('conditions', TType.LIST, 2)
+            oprot.writeListBegin(TType.STRUCT, len(self.conditions))
+            for iter91 in self.conditions:
+                iter91.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.updates is not None:
+            oprot.writeFieldBegin('updates', TType.LIST, 3)
+            oprot.writeListBegin(TType.STRUCT, len(self.updates))
+            for iter92 in self.updates:
+                iter92.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-class ConditionalWriterOptions:
-  """
-  Attributes:
-   - maxMemory
-   - timeoutMs
-   - threads
-   - authorizations
-   - durability
-  """
+    def validate(self):
+        return
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.I64, 'maxMemory', None, None, ), # 1
-    (2, TType.I64, 'timeoutMs', None, None, ), # 2
-    (3, TType.I32, 'threads', None, None, ), # 3
-    (4, TType.SET, 'authorizations', (TType.STRING,None), None, ), # 4
-    (5, TType.I32, 'durability', None, None, ), # 5
-  )
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __init__(self, maxMemory=None, timeoutMs=None, threads=None, authorizations=None, durability=None,):
-    self.maxMemory = maxMemory
-    self.timeoutMs = timeoutMs
-    self.threads = threads
-    self.authorizations = authorizations
-    self.durability = durability
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  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.I64:
-          self.maxMemory = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.I64:
-          self.timeoutMs = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.I32:
-          self.threads = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.SET:
-          self.authorizations = set()
-          (_etype96, _size93) = iprot.readSetBegin()
-          for _i97 in xrange(_size93):
-            _elem98 = iprot.readString()
-            self.authorizations.add(_elem98)
-          iprot.readSetEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.I32:
-          self.durability = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def __ne__(self, other):
+        return not (self == other)
 
-  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('ConditionalWriterOptions')
-    if self.maxMemory is not None:
-      oprot.writeFieldBegin('maxMemory', TType.I64, 1)
-      oprot.writeI64(self.maxMemory)
-      oprot.writeFieldEnd()
-    if self.timeoutMs is not None:
-      oprot.writeFieldBegin('timeoutMs', TType.I64, 2)
-      oprot.writeI64(self.timeoutMs)
-      oprot.writeFieldEnd()
-    if self.threads is not None:
-      oprot.writeFieldBegin('threads', TType.I32, 3)
-      oprot.writeI32(self.threads)
-      oprot.writeFieldEnd()
-    if self.authorizations is not None:
-      oprot.writeFieldBegin('authorizations', TType.SET, 4)
-      oprot.writeSetBegin(TType.STRING, len(self.authorizations))
-      for iter99 in self.authorizations:
-        oprot.writeString(iter99)
-      oprot.writeSetEnd()
-      oprot.writeFieldEnd()
-    if self.durability is not None:
-      oprot.writeFieldBegin('durability', TType.I32, 5)
-      oprot.writeI32(self.durability)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
 
-  def validate(self):
-    return
+class ConditionalWriterOptions(object):
+    """
+    Attributes:
+     - maxMemory
+     - timeoutMs
+     - threads
+     - authorizations
+     - durability
+    """
 
+    thrift_spec = (
+        None,  # 0
+        (1, TType.I64, 'maxMemory', None, None, ),  # 1
+        (2, TType.I64, 'timeoutMs', None, None, ),  # 2
+        (3, TType.I32, 'threads', None, None, ),  # 3
+        (4, TType.SET, 'authorizations', (TType.STRING, 'BINARY', False), None, ),  # 4
+        (5, TType.I32, 'durability', None, None, ),  # 5
+    )
 
-  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 __init__(self, maxMemory=None, timeoutMs=None, threads=None, authorizations=None, durability=None,):
+        self.maxMemory = maxMemory
+        self.timeoutMs = timeoutMs
+        self.threads = threads
+        self.authorizations = authorizations
+        self.durability = durability
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.I64:
+                    self.maxMemory = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.I64:
+                    self.timeoutMs = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.I32:
+                    self.threads = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.SET:
+                    self.authorizations = set()
+                    (_etype96, _size93) = iprot.readSetBegin()
+                    for _i97 in range(_size93):
+                        _elem98 = iprot.readBinary()
+                        self.authorizations.add(_elem98)
+                    iprot.readSetEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.I32:
+                    self.durability = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('ConditionalWriterOptions')
+        if self.maxMemory is not None:
+            oprot.writeFieldBegin('maxMemory', TType.I64, 1)
+            oprot.writeI64(self.maxMemory)
+            oprot.writeFieldEnd()
+        if self.timeoutMs is not None:
+            oprot.writeFieldBegin('timeoutMs', TType.I64, 2)
+            oprot.writeI64(self.timeoutMs)
+            oprot.writeFieldEnd()
+        if self.threads is not None:
+            oprot.writeFieldBegin('threads', TType.I32, 3)
+            oprot.writeI32(self.threads)
+            oprot.writeFieldEnd()
+        if self.authorizations is not None:
+            oprot.writeFieldBegin('authorizations', TType.SET, 4)
+            oprot.writeSetBegin(TType.STRING, len(self.authorizations))
+            for iter99 in self.authorizations:
+                oprot.writeBinary(iter99)
+            oprot.writeSetEnd()
+            oprot.writeFieldEnd()
+        if self.durability is not None:
+            oprot.writeFieldBegin('durability', TType.I32, 5)
+            oprot.writeI32(self.durability)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def __ne__(self, other):
-    return not (self == other)
+    def validate(self):
+        return
 
-class ActiveScan:
-  """
-  Attributes:
-   - client
-   - user
-   - table
-   - age
-   - idleTime
-   - type
-   - state
-   - extent
-   - columns
-   - iterators
-   - authorizations
-  """
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'client', None, None, ), # 1
-    (2, TType.STRING, 'user', None, None, ), # 2
-    (3, TType.STRING, 'table', None, None, ), # 3
-    (4, TType.I64, 'age', None, None, ), # 4
-    (5, TType.I64, 'idleTime', None, None, ), # 5
-    (6, TType.I32, 'type', None, None, ), # 6
-    (7, TType.I32, 'state', None, None, ), # 7
-    (8, TType.STRUCT, 'extent', (KeyExtent, KeyExtent.thrift_spec), None, ), # 8
-    (9, TType.LIST, 'columns', (TType.STRUCT,(Column, Column.thrift_spec)), None, ), # 9
-    (10, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 10
-    (11, TType.LIST, 'authorizations', (TType.STRING,None), None, ), # 11
-  )
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __init__(self, client=None, user=None, table=None, age=None, idleTime=None, type=None, state=None, extent=None, columns=None, iterators=None, authorizations=None,):
-    self.client = client
-    self.user = user
-    self.table = table
-    self.age = age
-    self.idleTime = idleTime
-    self.type = type
-    self.state = state
-    self.extent = extent
-    self.columns = columns
-    self.iterators = iterators
-    self.authorizations = authorizations
+    def __ne__(self, other):
+        return not (self == other)
 
-  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.client = 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.table = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.I64:
-          self.age = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.I64:
-          self.idleTime = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 6:
-        if ftype == TType.I32:
-          self.type = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      elif fid == 7:
-        if ftype == TType.I32:
-          self.state = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      elif fid == 8:
-        if ftype == TType.STRUCT:
-          self.extent = KeyExtent()
-          self.extent.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 9:
-        if ftype == TType.LIST:
-          self.columns = []
-          (_etype103, _size100) = iprot.readListBegin()
-          for _i104 in xrange(_size100):
-            _elem105 = Column()
-            _elem105.read(iprot)
-            self.columns.append(_elem105)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 10:
-        if ftype == TType.LIST:
-          self.iterators = []
-          (_etype109, _size106) = iprot.readListBegin()
-          for _i110 in xrange(_size106):
-            _elem111 = IteratorSetting()
-            _elem111.read(iprot)
-            self.iterators.append(_elem111)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 11:
-        if ftype == TType.LIST:
-          self.authorizations = []
-          (_etype115, _size112) = iprot.readListBegin()
-          for _i116 in xrange(_size112):
-            _elem117 = iprot.readString()
-            self.authorizations.append(_elem117)
-          iprot.readListEnd()
-        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('ActiveScan')
-    if self.client is not None:
-      oprot.writeFieldBegin('client', TType.STRING, 1)
-      oprot.writeString(self.client)
-      oprot.writeFieldEnd()
-    if self.user is not None:
-      oprot.writeFieldBegin('user', TType.STRING, 2)
-      oprot.writeString(self.user)
-      oprot.writeFieldEnd()
-    if self.table is not None:
-      oprot.writeFieldBegin('table', TType.STRING, 3)
-      oprot.writeString(self.table)
-      oprot.writeFieldEnd()
-    if self.age is not None:
-      oprot.writeFieldBegin('age', TType.I64, 4)
-      oprot.writeI64(self.age)
-      oprot.writeFieldEnd()
-    if self.idleTime is not None:
-      oprot.writeFieldBegin('idleTime', TType.I64, 5)
-      oprot.writeI64(self.idleTime)
-      oprot.writeFieldEnd()
-    if self.type is not None:
-      oprot.writeFieldBegin('type', TType.I32, 6)
-      oprot.writeI32(self.type)
-      oprot.writeFieldEnd()
-    if self.state is not None:
-      oprot.writeFieldBegin('state', TType.I32, 7)
-      oprot.writeI32(self.state)
-      oprot.writeFieldEnd()
-    if self.extent is not None:
-      oprot.writeFieldBegin('extent', TType.STRUCT, 8)
-      self.extent.write(oprot)
-      oprot.writeFieldEnd()
-    if self.columns is not None:
-      oprot.writeFieldBegin('columns', TType.LIST, 9)
-      oprot.writeListBegin(TType.STRUCT, len(self.columns))
-      for iter118 in self.columns:
-        iter118.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.iterators is not None:
-      oprot.writeFieldBegin('iterators', TType.LIST, 10)
-      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
-      for iter119 in self.iterators:
-        iter119.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.authorizations is not None:
-      oprot.writeFieldBegin('authorizations', TType.LIST, 11)
-      oprot.writeListBegin(TType.STRING, len(self.authorizations))
-      for iter120 in self.authorizations:
-        oprot.writeString(iter120)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+class ActiveScan(object):
+    """
+    Attributes:
+     - client
+     - user
+     - table
+     - age
+     - idleTime
+     - type
+     - state
+     - extent
+     - columns
+     - iterators
+     - authorizations
+    """
 
-  def validate(self):
-    return
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'client', 'UTF8', None, ),  # 1
+        (2, TType.STRING, 'user', 'UTF8', None, ),  # 2
+        (3, TType.STRING, 'table', 'UTF8', None, ),  # 3
+        (4, TType.I64, 'age', None, None, ),  # 4
+        (5, TType.I64, 'idleTime', None, None, ),  # 5
+        (6, TType.I32, 'type', None, None, ),  # 6
+        (7, TType.I32, 'state', None, None, ),  # 7
+        (8, TType.STRUCT, 'extent', (KeyExtent, KeyExtent.thrift_spec), None, ),  # 8
+        (9, TType.LIST, 'columns', (TType.STRUCT, (Column, Column.thrift_spec), False), None, ),  # 9
+        (10, TType.LIST, 'iterators', (TType.STRUCT, (IteratorSetting, IteratorSetting.thrift_spec), False), None, ),  # 10
+        (11, TType.LIST, 'authorizations', (TType.STRING, 'BINARY', False), None, ),  # 11
+    )
 
+    def __init__(self, client=None, user=None, table=None, age=None, idleTime=None, type=None, state=None, extent=None, columns=None, iterators=None, authorizations=None,):
+        self.client = client
+        self.user = user
+        self.table = table
+        self.age = age
+        self.idleTime = idleTime
+        self.type = type
+        self.state = state
+        self.extent = extent
+        self.columns = columns
+        self.iterators = iterators
+        self.authorizations = authorizations
 
-  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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.client = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.STRING:
+                    self.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.STRING:
+                    self.table = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.I64:
+                    self.age = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.I64:
+                    self.idleTime = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 6:
+                if ftype == TType.I32:
+                    self.type = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 7:
+                if ftype == TType.I32:
+                    self.state = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 8:
+                if ftype == TType.STRUCT:
+                    self.extent = KeyExtent()
+                    self.extent.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 9:
+                if ftype == TType.LIST:
+                    self.columns = []
+                    (_etype103, _size100) = iprot.readListBegin()
+                    for _i104 in range(_size100):
+                        _elem105 = Column()
+                        _elem105.read(iprot)
+                        self.columns.append(_elem105)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 10:
+                if ftype == TType.LIST:
+                    self.iterators = []
+                    (_etype109, _size106) = iprot.readListBegin()
+                    for _i110 in range(_size106):
+                        _elem111 = IteratorSetting()
+                        _elem111.read(iprot)
+                        self.iterators.append(_elem111)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 11:
+                if ftype == TType.LIST:
+                    self.authorizations = []
+                    (_etype115, _size112) = iprot.readListBegin()
+                    for _i116 in range(_size112):
+                        _elem117 = iprot.readBinary()
+                        self.authorizations.append(_elem117)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('ActiveScan')
+        if self.client is not None:
+            oprot.writeFieldBegin('client', TType.STRING, 1)
+            oprot.writeString(self.client.encode('utf-8') if sys.version_info[0] == 2 else self.client)
+            oprot.writeFieldEnd()
+        if self.user is not None:
+            oprot.writeFieldBegin('user', TType.STRING, 2)
+            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
+            oprot.writeFieldEnd()
+        if self.table is not None:
+            oprot.writeFieldBegin('table', TType.STRING, 3)
+            oprot.writeString(self.table.encode('utf-8') if sys.version_info[0] == 2 else self.table)
+            oprot.writeFieldEnd()
+        if self.age is not None:
+            oprot.writeFieldBegin('age', TType.I64, 4)
+            oprot.writeI64(self.age)
+            oprot.writeFieldEnd()
+        if self.idleTime is not None:
+            oprot.writeFieldBegin('idleTime', TType.I64, 5)
+            oprot.writeI64(self.idleTime)
+            oprot.writeFieldEnd()
+        if self.type is not None:
+            oprot.writeFieldBegin('type', TType.I32, 6)
+            oprot.writeI32(self.type)
+            oprot.writeFieldEnd()
+        if self.state is not None:
+            oprot.writeFieldBegin('state', TType.I32, 7)
+            oprot.writeI32(self.state)
+            oprot.writeFieldEnd()
+        if self.extent is not None:
+            oprot.writeFieldBegin('extent', TType.STRUCT, 8)
+            self.extent.write(oprot)
+            oprot.writeFieldEnd()
+        if self.columns is not None:
+            oprot.writeFieldBegin('columns', TType.LIST, 9)
+            oprot.writeListBegin(TType.STRUCT, len(self.columns))
+            for iter118 in self.columns:
+                iter118.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.iterators is not None:
+            oprot.writeFieldBegin('iterators', TType.LIST, 10)
+            oprot.writeListBegin(TType.STRUCT, len(self.iterators))
+            for iter119 in self.iterators:
+                iter119.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.authorizations is not None:
+            oprot.writeFieldBegin('authorizations', TType.LIST, 11)
+            oprot.writeListBegin(TType.STRING, len(self.authorizations))
+            for iter120 in self.authorizations:
+                oprot.writeBinary(iter120)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def validate(self):
+        return
 
-  def __ne__(self, other):
-    return not (self == other)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-class ActiveCompaction:
-  """
-  Attributes:
-   - extent
-   - age
-   - inputFiles
-   - outputFile
-   - type
-   - reason
-   - localityGroup
-   - entriesRead
-   - entriesWritten
-   - iterators
-  """
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRUCT, 'extent', (KeyExtent, KeyExtent.thrift_spec), None, ), # 1
-    (2, TType.I64, 'age', None, None, ), # 2
-    (3, TType.LIST, 'inputFiles', (TType.STRING,None), None, ), # 3
-    (4, TType.STRING, 'outputFile', None, None, ), # 4
-    (5, TType.I32, 'type', None, None, ), # 5
-    (6, TType.I32, 'reason', None, None, ), # 6
-    (7, TType.STRING, 'localityGroup', None, None, ), # 7
-    (8, TType.I64, 'entriesRead', None, None, ), # 8
-    (9, TType.I64, 'entriesWritten', None, None, ), # 9
-    (10, TType.LIST, 'iterators', (TType.STRUCT,(IteratorSetting, IteratorSetting.thrift_spec)), None, ), # 10
-  )
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __init__(self, extent=None, age=None, inputFiles=None, outputFile=None, type=None, reason=None, localityGroup=None, entriesRead=None, entriesWritten=None, iterators=None,):
-    self.extent = extent
-    self.age = age
-    self.inputFiles = inputFiles
-    self.outputFile = outputFile
-    self.type = type
-    self.reason = reason
-    self.localityGroup = localityGroup
-    self.entriesRead = entriesRead
-    self.entriesWritten = entriesWritten
-    self.iterators = iterators
 
-  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.extent = KeyExtent()
-          self.extent.read(iprot)
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.I64:
-          self.age = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.LIST:
-          self.inputFiles = []
-          (_etype124, _size121) = iprot.readListBegin()
-          for _i125 in xrange(_size121):
-            _elem126 = iprot.readString()
-            self.inputFiles.append(_elem126)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.STRING:
-          self.outputFile = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.I32:
-          self.type = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      elif fid == 6:
-        if ftype == TType.I32:
-          self.reason = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      elif fid == 7:
-        if ftype == TType.STRING:
-          self.localityGroup = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 8:
-        if ftype == TType.I64:
-          self.entriesRead = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 9:
-        if ftype == TType.I64:
-          self.entriesWritten = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 10:
-        if ftype == TType.LIST:
-          self.iterators = []
-          (_etype130, _size127) = iprot.readListBegin()
-          for _i131 in xrange(_size127):
-            _elem132 = IteratorSetting()
-            _elem132.read(iprot)
-            self.iterators.append(_elem132)
-          iprot.readListEnd()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+class ActiveCompaction(object):
+    """
+    Attributes:
+     - extent
+     - age
+     - inputFiles
+     - outputFile
+     - type
+     - reason
+     - localityGroup
+     - entriesRead
+     - entriesWritten
+     - iterators
+    """
 
-  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('ActiveCompaction')
-    if self.extent is not None:
-      oprot.writeFieldBegin('extent', TType.STRUCT, 1)
-      self.extent.write(oprot)
-      oprot.writeFieldEnd()
-    if self.age is not None:
-      oprot.writeFieldBegin('age', TType.I64, 2)
-      oprot.writeI64(self.age)
-      oprot.writeFieldEnd()
-    if self.inputFiles is not None:
-      oprot.writeFieldBegin('inputFiles', TType.LIST, 3)
-      oprot.writeListBegin(TType.STRING, len(self.inputFiles))
-      for iter133 in self.inputFiles:
-        oprot.writeString(iter133)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    if self.outputFile is not None:
-      oprot.writeFieldBegin('outputFile', TType.STRING, 4)
-      oprot.writeString(self.outputFile)
-      oprot.writeFieldEnd()
-    if self.type is not None:
-      oprot.writeFieldBegin('type', TType.I32, 5)
-      oprot.writeI32(self.type)
-      oprot.writeFieldEnd()
-    if self.reason is not None:
-      oprot.writeFieldBegin('reason', TType.I32, 6)
-      oprot.writeI32(self.reason)
-      oprot.writeFieldEnd()
-    if self.localityGroup is not None:
-      oprot.writeFieldBegin('localityGroup', TType.STRING, 7)
-      oprot.writeString(self.localityGroup)
-      oprot.writeFieldEnd()
-    if self.entriesRead is not None:
-      oprot.writeFieldBegin('entriesRead', TType.I64, 8)
-      oprot.writeI64(self.entriesRead)
-      oprot.writeFieldEnd()
-    if self.entriesWritten is not None:
-      oprot.writeFieldBegin('entriesWritten', TType.I64, 9)
-      oprot.writeI64(self.entriesWritten)
-      oprot.writeFieldEnd()
-    if self.iterators is not None:
-      oprot.writeFieldBegin('iterators', TType.LIST, 10)
-      oprot.writeListBegin(TType.STRUCT, len(self.iterators))
-      for iter134 in self.iterators:
-        iter134.write(oprot)
-      oprot.writeListEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRUCT, 'extent', (KeyExtent, KeyExtent.thrift_spec), None, ),  # 1
+        (2, TType.I64, 'age', None, None, ),  # 2
+        (3, TType.LIST, 'inputFiles', (TType.STRING, 'UTF8', False), None, ),  # 3
+        (4, TType.STRING, 'outputFile', 'UTF8', None, ),  # 4
+        (5, TType.I32, 'type', None, None, ),  # 5
+        (6, TType.I32, 'reason', None, None, ),  # 6
+        (7, TType.STRING, 'localityGroup', 'UTF8', None, ),  # 7
+        (8, TType.I64, 'entriesRead', None, None, ),  # 8
+        (9, TType.I64, 'entriesWritten', None, None, ),  # 9
+        (10, TType.LIST, 'iterators', (TType.STRUCT, (IteratorSetting, IteratorSetting.thrift_spec), False), None, ),  # 10
+    )
 
-  def validate(self):
-    return
+    def __init__(self, extent=None, age=None, inputFiles=None, outputFile=None, type=None, reason=None, localityGroup=None, entriesRead=None, entriesWritten=None, iterators=None,):
+        self.extent = extent
+        self.age = age
+        self.inputFiles = inputFiles
+        self.outputFile = outputFile
+        self.type = type
+        self.reason = reason
+        self.localityGroup = localityGroup
+        self.entriesRead = entriesRead
+        self.entriesWritten = entriesWritten
+        self.iterators = iterators
 
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.extent = KeyExtent()
+                    self.extent.read(iprot)
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.I64:
+                    self.age = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.LIST:
+                    self.inputFiles = []
+                    (_etype124, _size121) = iprot.readListBegin()
+                    for _i125 in range(_size121):
+                        _elem126 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.inputFiles.append(_elem126)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.STRING:
+                    self.outputFile = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.I32:
+                    self.type = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 6:
+                if ftype == TType.I32:
+                    self.reason = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 7:
+                if ftype == TType.STRING:
+                    self.localityGroup = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 8:
+                if ftype == TType.I64:
+                    self.entriesRead = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 9:
+                if ftype == TType.I64:
+                    self.entriesWritten = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 10:
+                if ftype == TType.LIST:
+                    self.iterators = []
+                    (_etype130, _size127) = iprot.readListBegin()
+                    for _i131 in range(_size127):
+                        _elem132 = IteratorSetting()
+                        _elem132.read(iprot)
+                        self.iterators.append(_elem132)
+                    iprot.readListEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  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 write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('ActiveCompaction')
+        if self.extent is not None:
+            oprot.writeFieldBegin('extent', TType.STRUCT, 1)
+            self.extent.write(oprot)
+            oprot.writeFieldEnd()
+        if self.age is not None:
+            oprot.writeFieldBegin('age', TType.I64, 2)
+            oprot.writeI64(self.age)
+            oprot.writeFieldEnd()
+        if self.inputFiles is not None:
+            oprot.writeFieldBegin('inputFiles', TType.LIST, 3)
+            oprot.writeListBegin(TType.STRING, len(self.inputFiles))
+            for iter133 in self.inputFiles:
+                oprot.writeString(iter133.encode('utf-8') if sys.version_info[0] == 2 else iter133)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        if self.outputFile is not None:
+            oprot.writeFieldBegin('outputFile', TType.STRING, 4)
+            oprot.writeString(self.outputFile.encode('utf-8') if sys.version_info[0] == 2 else self.outputFile)
+            oprot.writeFieldEnd()
+        if self.type is not None:
+            oprot.writeFieldBegin('type', TType.I32, 5)
+            oprot.writeI32(self.type)
+            oprot.writeFieldEnd()
+        if self.reason is not None:
+            oprot.writeFieldBegin('reason', TType.I32, 6)
+            oprot.writeI32(self.reason)
+            oprot.writeFieldEnd()
+        if self.localityGroup is not None:
+            oprot.writeFieldBegin('localityGroup', TType.STRING, 7)
+            oprot.writeString(self.localityGroup.encode('utf-8') if sys.version_info[0] == 2 else self.localityGroup)
+            oprot.writeFieldEnd()
+        if self.entriesRead is not None:
+            oprot.writeFieldBegin('entriesRead', TType.I64, 8)
+            oprot.writeI64(self.entriesRead)
+            oprot.writeFieldEnd()
+        if self.entriesWritten is not None:
+            oprot.writeFieldBegin('entriesWritten', TType.I64, 9)
+            oprot.writeI64(self.entriesWritten)
+            oprot.writeFieldEnd()
+        if self.iterators is not None:
+            oprot.writeFieldBegin('iterators', TType.LIST, 10)
+            oprot.writeListBegin(TType.STRUCT, len(self.iterators))
+            for iter134 in self.iterators:
+                iter134.write(oprot)
+            oprot.writeListEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def validate(self):
+        return
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __ne__(self, other):
-    return not (self == other)
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-class WriterOptions:
-  """
-  Attributes:
-   - maxMemory
-   - latencyMs
-   - timeoutMs
-   - threads
-   - durability
-  """
+    def __ne__(self, other):
+        return not (self == other)
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.I64, 'maxMemory', None, None, ), # 1
-    (2, TType.I64, 'latencyMs', None, None, ), # 2
-    (3, TType.I64, 'timeoutMs', None, None, ), # 3
-    (4, TType.I32, 'threads', None, None, ), # 4
-    (5, TType.I32, 'durability', None, None, ), # 5
-  )
 
-  def __init__(self, maxMemory=None, latencyMs=None, timeoutMs=None, threads=None, durability=None,):
-    self.maxMemory = maxMemory
-    self.latencyMs = latencyMs
-    self.timeoutMs = timeoutMs
-    self.threads = threads
-    self.durability = durability
+class WriterOptions(object):
+    """
+    Attributes:
+     - maxMemory
+     - latencyMs
+     - timeoutMs
+     - threads
+     - durability
+    """
 
-  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.I64:
-          self.maxMemory = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.I64:
-          self.latencyMs = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 3:
-        if ftype == TType.I64:
-          self.timeoutMs = iprot.readI64()
-        else:
-          iprot.skip(ftype)
-      elif fid == 4:
-        if ftype == TType.I32:
-          self.threads = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      elif fid == 5:
-        if ftype == TType.I32:
-          self.durability = iprot.readI32()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    thrift_spec = (
+        None,  # 0
+        (1, TType.I64, 'maxMemory', None, None, ),  # 1
+        (2, TType.I64, 'latencyMs', None, None, ),  # 2
+        (3, TType.I64, 'timeoutMs', None, None, ),  # 3
+        (4, TType.I32, 'threads', None, None, ),  # 4
+        (5, TType.I32, 'durability', None, None, ),  # 5
+    )
 
-  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('WriterOptions')
-    if self.maxMemory is not None:
-      oprot.writeFieldBegin('maxMemory', TType.I64, 1)
-      oprot.writeI64(self.maxMemory)
-      oprot.writeFieldEnd()
-    if self.latencyMs is not None:
-      oprot.writeFieldBegin('latencyMs', TType.I64, 2)
-      oprot.writeI64(self.latencyMs)
-      oprot.writeFieldEnd()
-    if self.timeoutMs is not None:
-      oprot.writeFieldBegin('timeoutMs', TType.I64, 3)
-      oprot.writeI64(self.timeoutMs)
-      oprot.writeFieldEnd()
-    if self.threads is not None:
-      oprot.writeFieldBegin('threads', TType.I32, 4)
-      oprot.writeI32(self.threads)
-      oprot.writeFieldEnd()
-    if self.durability is not None:
-      oprot.writeFieldBegin('durability', TType.I32, 5)
-      oprot.writeI32(self.durability)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def __init__(self, maxMemory=None, latencyMs=None, timeoutMs=None, threads=None, durability=None,):
+        self.maxMemory = maxMemory
+        self.latencyMs = latencyMs
+        self.timeoutMs = timeoutMs
+        self.threads = threads
+        self.durability = durability
 
-  def validate(self):
-    return
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.I64:
+                    self.maxMemory = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.I64:
+                    self.latencyMs = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 3:
+                if ftype == TType.I64:
+                    self.timeoutMs = iprot.readI64()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 4:
+                if ftype == TType.I32:
+                    self.threads = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 5:
+                if ftype == TType.I32:
+                    self.durability = iprot.readI32()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('WriterOptions')
+        if self.maxMemory is not None:
+            oprot.writeFieldBegin('maxMemory', TType.I64, 1)
+            oprot.writeI64(self.maxMemory)
+            oprot.writeFieldEnd()
+        if self.latencyMs is not None:
+            oprot.writeFieldBegin('latencyMs', TType.I64, 2)
+            oprot.writeI64(self.latencyMs)
+            oprot.writeFieldEnd()
+        if self.timeoutMs is not None:
+            oprot.writeFieldBegin('timeoutMs', TType.I64, 3)
+            oprot.writeI64(self.timeoutMs)
+            oprot.writeFieldEnd()
+        if self.threads is not None:
+            oprot.writeFieldBegin('threads', TType.I32, 4)
+            oprot.writeI32(self.threads)
+            oprot.writeFieldEnd()
+        if self.durability is not None:
+            oprot.writeFieldBegin('durability', TType.I32, 5)
+            oprot.writeI32(self.durability)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  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 validate(self):
+        return
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __ne__(self, other):
-    return not (self == other)
+    def __ne__(self, other):
+        return not (self == other)
 
-class CompactionStrategyConfig:
-  """
-  Attributes:
-   - className
-   - options
-  """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'className', None, None, ), # 1
-    (2, TType.MAP, 'options', (TType.STRING,None,TType.STRING,None), None, ), # 2
-  )
+class CompactionStrategyConfig(object):
+    """
+    Attributes:
+     - className
+     - options
+    """
 
-  def __init__(self, className=None, options=None,):
-    self.className = className
-    self.options = options
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'className', 'UTF8', None, ),  # 1
+        (2, TType.MAP, 'options', (TType.STRING, 'UTF8', TType.STRING, 'UTF8', False), None, ),  # 2
+    )
 
-  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.className = iprot.readString()
-        else:
-          iprot.skip(ftype)
-      elif fid == 2:
-        if ftype == TType.MAP:
-          self.options = {}
-          (_ktype136, _vtype137, _size135 ) = iprot.readMapBegin()
-          for _i139 in xrange(_size135):
-            _key140 = iprot.readString()
-            _val141 = iprot.readString()
-            self.options[_key140] = _val141
-          iprot.readMapEnd()
-        else:
-          iprot.skip(ftype)
-      else:
-        iprot.skip(ftype)
-      iprot.readFieldEnd()
-    iprot.readStructEnd()
+    def __init__(self, className=None, options=None,):
+        self.className = className
+        self.options = options
 
-  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('CompactionStrategyConfig')
-    if self.className is not None:
-      oprot.writeFieldBegin('className', TType.STRING, 1)
-      oprot.writeString(self.className)
-      oprot.writeFieldEnd()
-    if self.options is not None:
-      oprot.writeFieldBegin('options', TType.MAP, 2)
-      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.options))
-      for kiter142,viter143 in self.options.items():
-        oprot.writeString(kiter142)
-        oprot.writeString(viter143)
-      oprot.writeMapEnd()
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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.className = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                else:
+                    iprot.skip(ftype)
+            elif fid == 2:
+                if ftype == TType.MAP:
+                    self.options = {}
+                    (_ktype136, _vtype137, _size135) = iprot.readMapBegin()
+                    for _i139 in range(_size135):
+                        _key140 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        _val141 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
+                        self.options[_key140] = _val141
+                    iprot.readMapEnd()
+                else:
+                    iprot.skip(ftype)
+            else:
+                iprot.skip(ftype)
+            iprot.readFieldEnd()
+        iprot.readStructEnd()
 
-  def validate(self):
-    return
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('CompactionStrategyConfig')
+        if self.className is not None:
+            oprot.writeFieldBegin('className', TType.STRING, 1)
+            oprot.writeString(self.className.encode('utf-8') if sys.version_info[0] == 2 else self.className)
+            oprot.writeFieldEnd()
+        if self.options is not None:
+            oprot.writeFieldBegin('options', TType.MAP, 2)
+            oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.options))
+            for kiter142, viter143 in self.options.items():
+                oprot.writeString(kiter142.encode('utf-8') if sys.version_info[0] == 2 else kiter142)
+                oprot.writeString(viter143.encode('utf-8') if sys.version_info[0] == 2 else viter143)
+            oprot.writeMapEnd()
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
+    def validate(self):
+        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__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  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 __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __ne__(self, other):
-    return not (self == other)
 
 class UnknownScanner(TException):
-  """
-  Attributes:
-   - msg
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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('UnknownScanner')
-    if self.msg is not None:
-      oprot.writeFieldBegin('msg', TType.STRING, 1)
-      oprot.writeString(self.msg)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('UnknownScanner')
+        if self.msg is not None:
+            oprot.writeFieldBegin('msg', TType.STRING, 1)
+            oprot.writeString(self.msg.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
 
 class UnknownWriter(TException):
-  """
-  Attributes:
-   - msg
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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('UnknownWriter')
-    if self.msg is not None:
-      oprot.writeFieldBegin('msg', TType.STRING, 1)
-      oprot.writeString(self.msg)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('UnknownWriter')
+        if self.msg is not None:
+            oprot.writeFieldBegin('msg', TType.STRING, 1)
+            oprot.writeString(self.msg.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
 
 class NoMoreEntriesException(TException):
-  """
-  Attributes:
-   - msg
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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('NoMoreEntriesException')
-    if self.msg is not None:
-      oprot.writeFieldBegin('msg', TType.STRING, 1)
-      oprot.writeString(self.msg)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('NoMoreEntriesException')
+        if self.msg is not None:
+            oprot.writeFieldBegin('msg', TType.STRING, 1)
+            oprot.writeString(self.msg.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
 
 class AccumuloException(TException):
-  """
-  Attributes:
-   - msg
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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('AccumuloException')
-    if self.msg is not None:
-      oprot.writeFieldBegin('msg', TType.STRING, 1)
-      oprot.writeString(self.msg)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('AccumuloException')
+        if self.msg is not None:
+            oprot.writeFieldBegin('msg', TType.STRING, 1)
+            oprot.writeString(self.msg.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
 
 class AccumuloSecurityException(TException):
-  """
-  Attributes:
-   - msg
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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('AccumuloSecurityException')
-    if self.msg is not None:
-      oprot.writeFieldBegin('msg', TType.STRING, 1)
-      oprot.writeString(self.msg)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('AccumuloSecurityException')
+        if self.msg is not None:
+            oprot.writeFieldBegin('msg', TType.STRING, 1)
+            oprot.writeString(self.msg.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
 
 class TableNotFoundException(TException):
-  """
-  Attributes:
-   - msg
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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('TableNotFoundException')
-    if self.msg is not None:
-      oprot.writeFieldBegin('msg', TType.STRING, 1)
-      oprot.writeString(self.msg)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('TableNotFoundException')
+        if self.msg is not None:
+            oprot.writeFieldBegin('msg', TType.STRING, 1)
+            oprot.writeString(self.msg.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
 
 class TableExistsException(TException):
-  """
-  Attributes:
-   - msg
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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('TableExistsException')
-    if self.msg is not None:
-      oprot.writeFieldBegin('msg', TType.STRING, 1)
-      oprot.writeString(self.msg)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('TableExistsException')
+        if self.msg is not None:
+            oprot.writeFieldBegin('msg', TType.STRING, 1)
+            oprot.writeString(self.msg.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  def __eq__(self, other):
-    return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
-
-  def __ne__(self, other):
-    return not (self == other)
 
 class MutationsRejectedException(TException):
-  """
-  Attributes:
-   - msg
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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('MutationsRejectedException')
-    if self.msg is not None:
-      oprot.writeFieldBegin('msg', TType.STRING, 1)
-      oprot.writeString(self.msg)
-      oprot.writeFieldEnd()
-    oprot.writeFieldStop()
-    oprot.writeStructEnd()
+    def write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
+            return
+        oprot.writeStructBegin('MutationsRejectedException')
+        if self.msg is not None:
+            oprot.writeFieldBegin('msg', TType.STRING, 1)
+            oprot.writeString(self.msg.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  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
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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 write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  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
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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 write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  def __repr__(self):
-    L = ['%s=%r' % (key, value)
-      for key, value in self.__dict__.iteritems()]
-    return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
+    def __ne__(self, other):
+        return not (self == other)
 
-  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
-  """
+    """
+    Attributes:
+     - msg
+    """
 
-  thrift_spec = (
-    None, # 0
-    (1, TType.STRING, 'msg', None, None, ), # 1
-  )
+    thrift_spec = (
+        None,  # 0
+        (1, TType.STRING, 'msg', 'UTF8', None, ),  # 1
+    )
 
-  def __init__(self, msg=None,):
-    self.msg = msg
+    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 read(self, iprot):
+        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
+            iprot._fast_decode(self, iprot, (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().decode('utf-8') if sys.version_info[0] == 2 else 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 write(self, oprot):
+        if oprot._fast_encode is not None and self.thrift_spec is not None:
+            oprot.trans.write(oprot._fast_encode(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.encode('utf-8') if sys.version_info[0] == 2 else self.msg)
+            oprot.writeFieldEnd()
+        oprot.writeFieldStop()
+        oprot.writeStructEnd()
 
-  def validate(self):
-    return
+    def validate(self):
+        return
 
+    def __str__(self):
+        return repr(self)
 
-  def __str__(self):
-    return repr(self)
+    def __repr__(self):
+        L = ['%s=%r' % (key, value)
+             for key, value in self.__dict__.items()]
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
 
-  def __hash__(self):
-    value = 17
-    value = (value * 31) ^ hash(self.msg)
-    return value
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
 
-  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)
+    def __ne__(self, other):
+        return not (self == other)
diff --git a/src/main/ruby/accumulo_proxy.rb b/src/main/ruby/accumulo_proxy.rb
index e02ba16..3c02507 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.3)
+# Autogenerated by Thrift Compiler (0.10.0)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
diff --git a/src/main/ruby/proxy_constants.rb b/src/main/ruby/proxy_constants.rb
index baaf9af..47eb2cf 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.3)
+# Autogenerated by Thrift Compiler (0.10.0)
 #
 # 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 ddf8a18..69a5da8 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.3)
+# Autogenerated by Thrift Compiler (0.10.0)
 #
 # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 #
